Автор Josh Hundley, известный так же как hundleyj
Я сейчас пишу онлайн-магазин на CakePHP и мне понадобился помощник, который изменял бы размер изображений, чтобы показывать на сайте эскизы (thumbnails).
Этот помощник изменит размер изображения «на лету» и сохранит его в кеше, чтобы в дальнейшем использовать готовое превью. Вам необходимо убедиться, что каталог imagecache доступен для записи. Будущие версии помощника возможно будут включать кадрирование изображения.
<?php
class ImageHelper extends Helper {
var $helpers = array('Html');
var $cacheDir = 'imagecache'; // relative to IMAGES_URL path
/**
* Автоматически изменяет размер изображения и возвращает форматированный IMG тег.
*
* @param string $path Путь до картинки, которая должна находиться внутри директории webroot/img/.
* @param integer $width Ширина создаваемого изображения
* @param integer $height Высота создаваемого изображения
* @param boolean $aspect Сохранять ли пропорции (default: true)
* @param array $htmlAttributes Массив HTML атрибутов.
* @param boolean $return Вернуть результат из метода или вывести его в общий поток. Это будет перекрывать AUTO_OUTPUT.
* @return mixed Возвращает строку или результат функции echo, в зависимости от параметра $return.
* @access public
*/
function resize($path, $width, $height, $aspect = true, $htmlAttributes = array(), $return = false) {
$types = array(1 => "gif", "jpeg", "png", "swf", "psd", "wbmp"); // используется для определения типа изображения
$fullpath = ROOT.DS.APP_DIR.DS.WEBROOT_DIR.DS.$this->themeWeb.IMAGES_URL;
$url = $fullpath.$path;
if (!($size = getimagesize($url)))
return; // не существует такого изображения
if ($aspect) { // считаем пропорции, если нас просили об этом
if (($size[1]/$height) > ($size[0]/$width)) // $size[0]:width, [1]:height, [2]:type
$width = ceil(($size[0]/$size[1]) * $height);
else
$height = ceil($width / ($size[0]/$size[1]));
}
$relfile = $this->webroot.$this->themeWeb.IMAGES_URL.$this->cacheDir.'/'.$width.'x'.$height.'_'.basename($path); // расположение файла
$cachefile = $fullpath.$this->cacheDir.DS.$width.'x'.$height.'_'.basename($path); // расположение на сервере
if (file_exists($cachefile)) {
$csize = getimagesize($cachefile);
$cached = ($csize[0] == $width && $csize[1] == $height); // изображение есть в кеше
if (@filemtime($cachefile) < @filemtime($url)) // проверяем дату кеша
$cached = false;
} else {
$cached = false;
}
if (!$cached) {
$resize = ($size[0] > $width || $size[1] > $height) || ($size[0] < $width || $size[1] < $height);
} else {
$resize = false;
}
if ($resize) {
$image = call_user_func('imagecreatefrom'.$types[$size[2]], $url);
if (function_exists("imagecreatetruecolor") && ($temp = imagecreatetruecolor ($width, $height))) {
imagecopyresampled ($temp, $image, 0, 0, 0, 0, $width, $height, $size[0], $size[1]);
} else {
$temp = imagecreate ($width, $height);
imagecopyresized ($temp, $image, 0, 0, 0, 0, $width, $height, $size[0], $size[1]);
}
call_user_func("image".$types[$size[2]], $temp, $cachefile);
imagedestroy ($image);
imagedestroy ($temp);
}
return $this->output(sprintf($this->Html->tags['image'], $relfile, $this->Html->parseHtmlOptions($htmlAttributes, null, '', ' ')), $return);
}
?>
Используем помощника так:
<? echo $image->resize('myimage.jpg', 150, 150, true) ?>
В этом помощнике есть ошибка.
Связана она с тем, что если на входе файл требуемой ширины и высоты (то есть, ресайзинг выполнять не нужно), скрипт не делает абсолютно ничего, но выводит ссылку на изображение в кеше.
Лечится добавлением else:
if ($resize) {
} else {
} else {
}
Кстати, последняя строчка у меня тоже работать не захотела (подозреваю, что из-за того, что версия кейка 1.2)
Поэтому ее заменил переписал так:
return $this->output($this->Html->image($relfile, $htmlAttributes));
А я вот использую библиотеку phpThumb. Очень удобно, указать надо всего-навсего путь к изображению с параметрами (ширина, высота, кадрирование)...
Вот тут есть «грубый» пример: http://bakery.cakephp.org/articles/view/thumbnails-generation-with-phpthumb