php动态生成图片实现浏览器缓存

当我们用php实现网站图片尺寸重写时,默认情况下浏览器不会将重写的图片缓存本地,现在我告诉你们怎样让浏览器缓存这样的图片数据。
// 在php脚本文件加上以下代码

session_start(); 
header("Cache-Control: private, max-age=10800, pre-check=10800");
header("Pragma: private");
header("Expires: " . date(DATE_RFC822,strtotime(" 2 day")));

1:如果浏览器已经有缓存版本,它会向后端传一个$_SERVER[‘HTTP_IF_MODIFIED_SINCE’] ,简单的做法我们只需要告诉浏览器用缓存即可。

if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])){
  // if the browser has a cached version of this image, send 304
  header('Last-Modified: '.$_SERVER['HTTP_IF_MODIFIED_SINCE'],true,304);
  exit;
}

2:如果浏览器有缓存版本,更明智的做法是,后端判断图片有没有更新,对应告知浏览器是否用缓存版本

$img = "some_image.png";
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) 
       && 
  (strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == filemtime($img))) {
  // send the last mod time of the file back
  header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($img)).' GMT', 
  true, 304);
  exit;
}

完整的代码

session_start(); 
header("Cache-Control: private, max-age=10800, pre-check=10800");
header("Pragma: private");
header("Expires: " . date(DATE_RFC822,strtotime(" 2 day")));
$img = "some_image.png"; 
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) 
       && 
  (strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == filemtime($img))) {
  // send the last mod time of the file back
  header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($img)).' GMT', 
  true, 304);
  exit;
}

// 裁剪图片,并且告知浏览器缓存图片

$is = new ImageSizer($img); 
$is->resizeImage(75); // resize image to 75px wide
// and here we send the image to the browser with all the stuff required for tell it to cache
header("Content-type: image/jpeg");
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($thumbnail)) . ' GMT');
$is->showImage();

图片裁剪类

class ImageSizer {

  var $_baseDir;
  var $_baseImg;
  var $_imgData;

  var $_newImg;
  var $_newData;
  var $_newFormat;

  var $_loadPath;
  var $_defaultColor = array(255,255,255);

  var $keepAspectRatio;
  var $makeBigger;

  function ImageSizer($baseDir) {
    $this->changeBaseDir($baseDir);
    $this->keepAspectRatio = true;
    $this->makeBigger = false;
  }

  function changeBaseDir($baseDir) {
    $this->_baseDir = $baseDir;
  }

  function setDefaultColor($r, $g, $b) {
    $this->_defaultColor = array($r, $g, $b);
  }

  function changeFormat($str) {
    $str = strtolower($str);
    if ($str == 'jpg') $str = "jpeg";
    $acceptable_formats = array('jpeg', 'gif', 'png');
    if (!in_array($str, $acceptable_formats)) return false;
    $this->_newFormat = $str;
  }

  function loadImage($imgPath) {
   // $this->_imgData = getimagesize($this->_baseDir. $imgPath);
    $this->_imgData = getimagesize( $imgPath);
    $this->_imgData['funcType'] = preg_replace('#image/#i', '', $this->_imgData['mime']);
    $acceptable_formats = array('jpeg', 'gif', 'png');
    if (!in_array($this->_imgData['funcType'], $acceptable_formats)) return false;
    $this->_newData = $this->_imgData;
    $funcName = 'imagecreatefrom' . $this->_imgData['funcType'];
    //$this->_newImg = $this->_baseImg  = $funcName($this->_baseDir. $imgPath);
    $this->_newImg = $this->_baseImg  = @$funcName( $imgPath);
    if(!$this->_baseImg){
        echo "
 Failed on this image $imgPath 
 ";
        return false;
    }
    $this->_loadPath = $imgPath;
    return true;
  }
    /*function genImageData(){
        $funcName = 'image'.$this->getNewType();
        $data = $funcName($this->_newImg ? $this->_newImg : $this->_baseImg);
        return $data;
    }*/
  function resizeImage($w, $h, $crop=false) {
    $current_w = $this->getWidth();
    $current_h = $this->getHeight();

    $src_x = $src_y = 0;
    $dst_x = $dst_y = 0;

    if($w && $h && $crop=="f"){
        // fill in the image centre it in white.
        // all the src stuff stays the same, just changing the destination suff
        $src_x = 0;
        $src_y = 0; 
        $current_h = $current_h;
        $current_w = $current_w;

        // the destination stuff changes
        if($h && $w){
            $h_percent = $percent = $h / $current_h;
            $w_percent = $percent = $w / $current_w;
             $percent = min($h_percent, $w_percent);
        }else if($h){
            $h_percent = $percent = $h / $current_h;
             $percent = $h_percent;
        }else if($w){
            $w_percent = $percent = $w / $current_w;
             $percent = $w_percent;
        }
        $dst_w = $current_w * $percent;
        $dst_h = $current_h * $percent;

        $new_w = $w;
        $new_h = $h;
        // work out destination x and y points

        $dst_x = ($new_w - $dst_w)/2;
        $dst_y = ($new_h - $dst_h)/2;

    }else if($w && $h && $crop=="c"){
        $dst_w = $w;
        $dst_h = $h;
        $new_w = $w;
        $new_h = $h;
        // if the image we are tyring to crop is smaller than the crop request we dont do aynthing
        if($w > $current_w || $h > $current_h){
            // the image is smaller than we are trying to crop!
        }else{
            //the image is bigger on x and y axis.
            // check if we can fit horizontally
            $w_percent = $current_w/$w;
            $h_percent = $current_h/$h;
            if($w_percent < $h_percent){
                $src_x = 0;
                $src_y = ($current_h/2) - (($h * $w_percent)/2);
                $current_w = $current_w;
                $current_h = ($h * $w_percent);
            }else{
                $src_x = ($current_w/2) - (($w * $h_percent)/2);
                $src_y = 0;
                $current_w = ($w * $h_percent);
                $current_h = $current_h;
            }

        }

    }else if ($this->keepAspectRatio) {
      $percent = 1;
     // if ($current_w > $w || $current_h > $h || $this->makeBigger) {
     $do_resize=false;
     if($w && $current_w > $w){
        $do_resize=true;
     }else if($h && $current_h > $h){
        $do_resize=true;
     }else if($w && $current_w < $w && $this->makeBigger){
        $do_resize=true;
     }else{
        // imaeg is alreaedy smaller than requested size
     }
      if (  $do_resize ) {
        if($h && $w){
            $h_percent = $percent = $h / $current_h;
            $w_percent = $percent = $w / $current_w;
             $percent = min($h_percent, $w_percent);
        }else if($h){
            $h_percent = $percent = $h / $current_h;
             $percent = $h_percent;
        }else if($w){
            $w_percent = $percent = $w / $current_w;
             $percent = $w_percent;
        }
      }

        $dst_w = $new_w = $current_w * $percent;
        $dst_h = $new_h = $current_h * $percent;
    } else{
        $dst_w = $new_w = $w;
        $dst_h = $new_h = $h;
    }

    $this->_newImg = ImageCreateTrueColor($new_w, $new_h);
    $this->_newData = array($new_w, $new_h);

    if ($this->getNewType() == 'png' || $this->getNewType() == 'gif') { // This preserves the transparency
      imageAlphaBlending($this->_newImg, false);
      imageSaveAlpha($this->_newImg, true);
    } else { // This is if converting from PNG to another image format
      list($r, $g, $b) = $this->_defaultColor;
      $color = imagecolorallocate($this->_newImg, $r, $g, $b);
      imagefilledrectangle($this->_newImg, 0,0, $new_w, $new_h, $color);
    }
                                                                                    // dst_w   dst_h   src_w       src_h
    imagecopyresampled($this->_newImg, $this->_baseImg, $dst_x, $dst_y,$src_x,$src_y, $dst_w, $dst_h, $current_w, $current_h);
    return true;
  }

  function showImage() {
    header('Content-type: ' . $this->getNewMime());
    $funcName = 'image'.$this->getNewType();
    $funcName($this->_newImg ? $this->_newImg : $this->_baseImg);
  }

  function saveToFile($fileloc) {
    $funcName = 'image'.$this->getNewType();
    $funcName($this->_newImg ? $this->_newImg : $this->_baseImg, $fileloc,100);
  }

  function addWatermark($pngloc,$offset_x=0) {
    $overlay = imagecreatefrompng($pngloc);
    imageAlphaBlending($overlay, false);
    imageSaveAlpha($overlay, true);
    imagecopy($this->_newImg, $overlay, (imagesx($this->_newImg))-(imagesx($overlay)+$offset_x), (imagesy($this->_newImg))-(imagesy($overlay)), 0, 0, imagesx($overlay), imagesy($overlay));
  }

  function getBaseDir() { return $this->_baseDir; }

  function getWidth() { return $this->_imgData[0]; }
  function getHeight() { return $this->_imgData[1]; }
  function getMime() { return $this->_imgData['mime']; }
  function getType() { return $this->_imgData['funcType'];}


  function getNewWidth() { return $this->_newData[0]; }
  function getNewHeight() { return $this->_newData[1]; }
  function getNewMime() {return $this->_newFormat ? 'image/' . $this->_newFormat : $this->_imgData['mime'];}
  function getNewType() {return $this->_newFormat ? $this->_newFormat : $this->_imgData['funcType'];}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值