Недавно была необходимость сделать функцию кэширования картинок на 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]
Плюс, для оптимизации картинок, можно повесить в крон .
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;

Идея прикольная.
Вот только реализация плохая, размеры картинок нельзя в гете передавать, а то твой сервер только и будет работать на ресайз изображений.
не понял? почему нельзя в гете передавать?
ну кто-нибудь будет дергать постоянно твое изображение с разными параметрами, будет небольшой ддос
ну если быть настолько паранойным, то добавь if исключений, что бы изображение было не более 400, и ширина кратна 20.
я сделал универсальный скрипта, а вам уже напильник в руки...
А почему при загрузке изображения в систему сразу не делать все необходимые размеры превью, оптимизировать и сохранять их?
Потому что, иногда требуется пережать в одну превьюшку, а иногда в 20, а если учесть, что все 19 и 20 могут быть не востребованы, то зачем плодить помойку?
Потому что, когда на крупном сайте, например магазине, в котором 3-10k товаров, меняется дизайн, можно просто поменять линк на ссылку и быть уверенным, что всё будет работать правильно, а не перегенерировать несколько тысяч картинок.
Мне кажется такой подход более универсальным.