Архив

PHP Кэширование картинок.

Недавно была необходимость сделать функцию кэширования картинок на php ну я и накидался простой скрипт, который отлично справляется с этой задачей.

Логика работы скрипта очень простая. Он смотрит входящие параметры, проверяет есть ли картинка заданного размера и отдает её если она есть или создает в подпапке  такую картинку и отдает её.

Это спасает нас от необходимости делать кучу ресайзов при загрузке картинки + это универсальный способ, который можно использовать в любом проекте.

Листинг под катом.

images_cache.php

// ------ Define's --------------

$file_folder = $_SERVER['DOCUMENT_ROOT']."/images";
$file_image  = $_GET['image'];
$file_size   = $_GET['size'];

// ------------------------------

if(empty($file_size)){
    $file_size = 50;
}

function img_resize($src, $dest, $width, $height, $rgb = 0xFFFFFF, $quality = 100) {
    $size = getimagesize($src);

    if ($size === false) {
        return false;
    }

    $format = strtolower(substr($size['mime'], strpos($size['mime'], '/') + 1));
    $icfunc = 'imagecreatefrom'.$format;

    if (!function_exists($icfunc)) {
        return false;
    }

    $x_ratio = $width  / $size[0];
    $y_ratio = $height / $size[1];

    if ($height == 0) {

        $y_ratio = $x_ratio;
        $height  = $y_ratio * $size[1];

    } elseif ($width == 0) {

        $x_ratio = $y_ratio;
        $width   = $x_ratio * $size[0];

    }

    $ratio       = min($x_ratio, $y_ratio);
    $use_x_ratio = ($x_ratio == $ratio);

    $new_width   = $use_x_ratio  ? $width  : floor($size[0] * $ratio);
    $new_height  = !$use_x_ratio ? $height : floor($size[1] * $ratio);
    $new_left    = $use_x_ratio  ? 0 : floor(($width - $new_width)   / 2);
    $new_top     = !$use_x_ratio ? 0 : floor(($height - $new_height) / 2);

    $isrc  = $icfunc($src);
    $idest = imagecreatetruecolor($width, $height);

    imagefill($idest, 0, 0, $rgb);
    imagecopyresampled($idest, $isrc, $new_left, $new_top, 0, 0, $new_width, $new_height, $size[0], $size[1]);

    imagejpeg($idest, $dest, $quality);

    imagedestroy($isrc);
    imagedestroy($idest);

    return true;
}

$file_destination_folder = $file_folder.'/'.$file_size.'/';
$file_destination        = $file_folder.'/'.$file_size.'/'.$file_image;

if(!file_exists($file_destination)){

    if (!is_dir($file_destination_folder)) {
        if(!mkdir($file_destination_folder, 0777)){
            exit();
        }
    }

    img_resize($file_folder.'/'.$file_image, $file_destination, $file_size, 0);
}

$file_final_size = getimagesize($file_destination);

header("Content-type: ".$file_final_size['mime']);
header('Content-Length: ' . filesize($file_destination));
readfile($file_destination);

Далее, что бы всё было красиво, нам нужно добавить запись в .htaccess, что бы наши картинки имели нормальные адреса

.htaccess

RewriteRule   ^image/([0-9]+)/(.*)$  images_cache.php?size=$1&image=$2 [L,QSA]

Плюс, для оптимизации картинок, можно повесить в крон shell скрипт от Александра Улизько.

images_optimize.sh

for file in `find . -iname "*.jpg" -or -iname "*.png" -or -iname "*.jpeg"`;do
  ext=${file##*.}
  if [ -n "$ext" ]; then
    if [ "$ext" = "jpg" ]; then
      echo "optimizing ${file} as jpeg file with jpegtran"
      jpegtran -copy none -optimize -perfect -outfile temp_abracadabra_filename.jpg $file
      mv -f temp_abracadabra_filename.jpg $file;
    fi
    if [ "$ext" = "jpeg" ]; then
      echo "optimizing ${file} as jpeg file with jpegtran"
      jpegtran -copy none -optimize -perfect -outfile temp_abracadabra_filename.jpeg $file
      mv -f temp_abracadabra_filename.jpeg $file;
    fi
    if [ "$ext" = "png" ]; then
      echo "optimizing ${file} as png file with pngcrush"
      pngcrush -rem alla -reduce -brute "$file" temp_abracadabra_filename.png;
      mv -f temp_abracadabra_filename.png $file;
    fi
  fi
done;

UPDATE: Часть вторая