В данный момент занимаюсь написанием небольшой админки для сайта фото-студии.
Работу выполняю на Yii+Booster. Используя CRUD-generator достаточно быстро набросал примерный функционал, но когда дошло дело до картинок, появились маленькие проблемы. Поискав на официальном сайте подходящее дополнение пришел к тому, что придется написать простенький и «легкий» виджет для моих нужд.
Поскольку это сайт фото-студии, то картинок, разумеется, на нем будет очень много, и просто необходима функция динамического ресайза картинок.
И так…
Цель
Создать виджет который будет создавать уменьшенную копию оригинального изображения, если таковой не существует, и выводить ее путь на сайте. А также будет легко настраиваться под наши нужды.
Реализация
Для начало создаем каталог kyimages
(имя нашего виджета) в папке \protected\extensions\
. В ней создаем файл KYImages.php
(опять же имя нашего виджета, так же должен называться и класс который мы вскоре создадим).
Теперь приступаем непосредственно к написанию самого виджета.
<?php class KYImages extends CWidget { public function run() { } }
А именно, создаем наш класс, который расширяет класс CWidget
и переопределяем его метод run()
.
В этом методе будет находится тело нашего виджета.
Поскольку наш виджет будет принимать параметры для ресайза картинки, огласим переменные, которые будут их хранить.
public $params = array(); //полученные параметры //параметры по умолчанию public $_params = array( 'image'=>'', //url каринки 'dimensions'=>'100x100', //желаемые размеры превью 'crop'=>true, //метод обработки (если true обрезать до указанных размеров, иначе - пропорционально уменьшить) 'quality'=>100, //качество );
Далее приступаем к написание непосредсвтенно действий выполняемых виджетом.
Представлю вам хорошо коментированный код функции
public function run() { define('WEBROOT',Yii::getPathOfAlias('webroot')); //корень приложения //преобразуем массив параметров по умолчанию в переменные extract($this->_params); //переопределяем полученными параметрами extract($this->params); $original_path = WEBROOT. dirname($image); //путь к папке с картинкой на сервере $original_image_path = WEBROOT . $image; //путь к самой картинке на сервере $dimensions = explode('x',$dimensions); // конвертируем размеры изображения вида "100х100" в массив $target_width = intval($dimensions[0]); //желаемая ширина $target_height = intval(empty($dimensions[1]) ? $dimensions[0] : $dimensions[1]); //желаемая высота $pcs = pathinfo($original_image_path); //казбиваем путь к картинке $name = explode('.',$pcs["basename"]); $name = $name[0]; //запоминаем имя файла $ext = $pcs["extension"]; //запоминаем расширение файла $new_name = $name . "_{$target_width}x{$target_height}" . '.' . $ext; //новое имя для файла $new_path = $original_path . "/{$target_width}x{$target_height}/" . $new_name; //путь для превью (рядом с оригиналом будет папка с именев вида "100х100") $true_path = dirname($image) . "/{$target_width}x{$target_height}/" . $new_name; //путь оносительно домена if (file_exists($new_path)) { //проверяем если превью уже существует echo $true_path; //если да, тогда просто возращаем путь, иначе генерируем превью } else { if (!file_exists($original_path . "/{$target_width}x{$target_height}/" )) { //проверяем создана ли папка для первью, создаем ессли нет mkdir($original_path . "/{$target_width}x{$target_height}/" ); } list($width, $height) = getimagesize($original_image_path); //запоминаем размеры оригинаьной картинки $mime = getimagesize($original_image_path); //получаем инфо о картинке $r = $width / $height; //пропорции if ($crop) { //проверяем установлена ли опция обрезки картинки, и задаем соответсвующее поведение if ($width > $height) { $width = ceil($width-($width*($r-$target_width/$target_height))); } else { $height = ceil($height-($height*($r-$target_width/$target_height))); } $newwidth = $target_width; $newheight = $target_width; } else { if ($target_width/$target_height > $r) { $newwidth = $target_height*$r; $newheight = $target_height; } else { $newheight = $target_width/$r; $newwidth = $target_width; } } switch($mime['mime']) //проверяем тип картинки, ив зависимот=сти от этого изменяем функции генерации и экспорта картинки { case 'image/gif': $creationFunction = 'imagecreatefromgif'; //фунция генерации $outputFunction = 'imagepng'; //функция экспорта $mime = 'image/png'; // конвертируем gif в png $quality = round(10 - ($quality / 10)); // для png качество задается от 1 до 9, а не как в jpeg от 1 до 100 break; case 'image/x-png': case 'image/png': $creationFunction = 'imagecreatefrompng'; $outputFunction = 'imagepng'; $quality = round(10 - ($quality / 10)); break; default: $creationFunction = 'imagecreatefromjpeg'; $outputFunction = 'imagejpeg'; break; } $src = $creationFunction($original_image_path); $dst = imagecreatetruecolor($newwidth, $newheight); imagecopyresampled($dst, $src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height); //генерируем превью $outputFunction($dst, $new_path, $quality); //сохраняем на диск // Чистим память imagedestroy($src); imagedestroy($dst); echo $true_path; //возращаем путь относительно домена } }
Вот и готово.
Вывод на сайте
<img src="<?php $this->widget('application.extensions.kyimages.KYImages',array('params'=>array('image'=>"/media/images/img.jpeg",'dimensions'=>'138x138'))); ?>">
Конечно вы скажете что можно было бы сделать чтоб виджет выводил сразу готовый тег <img>
, но мне требовалось именно так. Вы же можете изменить все как считаете нужным. Возможно вы знаете как можно оптимизировать мой код=)
<source lang="php"> <?php /** * KYImages extension controller action class * * PHP version 5.3 * * LICENSE: This source file is subject to GNU General Public License v2. * * @category Extensions * @package KYImages * author Ruslan Kyba <kybargr@gmail.com> * copyright 2013 Ruslan Kyba * version 0.1 * see Yii Framework */ class KYImages extends CWidget { public $params = array(); public $_params = array( 'image'=>'', 'dimensions'=>'100x100', 'crop'=>true, 'quality'=>100, ); public function run() { define('WEBROOT',Yii::getPathOfAlias('webroot')); //корень приложения //преобразуем массив параметров по умолчанию в переменные extract($this->_params); //переопределяем полученными параметрами extract($this->params); $original_path = WEBROOT. dirname($image); //путь к папке с картинкой на сервере $original_image_path = WEBROOT . $image; //путь к самой картинке на сервере $dimensions = explode('x',$dimensions); // конвертируем размеры изображения вида "100х100" в массив $target_width = intval($dimensions[0]); //желаемая ширина $target_height = intval(empty($dimensions[1]) ? $dimensions[0] : $dimensions[1]); //желаемая высота $pcs = pathinfo($original_image_path); //казбиваем путь к картинке $name = explode('.',$pcs["basename"]); $name = $name[0]; //запоминаем имя файла $ext = $pcs["extension"]; //запоминаем расширение файла $new_name = $name . "_{$target_width}x{$target_height}" . '.' . $ext; //новое имя для файла $new_path = $original_path . "/{$target_width}x{$target_height}/" . $new_name; //путь для превью (рядом с оригиналом будет папка с именев вида "100х100") $true_path = dirname($image) . "/{$target_width}x{$target_height}/" . $new_name; //путь оносительно домена if (file_exists($new_path)) { //проверяем если превью уже существует echo $true_path; //если да, тогда просто возращаем путь, иначе генерируем превью } else { if (!file_exists($original_path . "/{$target_width}x{$target_height}/" )) { //проверяем создана ли папка для первью, создаем ессли нет mkdir($original_path . "/{$target_width}x{$target_height}/" ); } list($width, $height) = getimagesize($original_image_path); //запоминаем размеры оригинаьной картинки $mime = getimagesize($original_image_path); //получаем инфо о картинке $r = $width / $height; //пропорции if ($crop) { //проверяем установлена ли опция обрезки картинки, и задаем соответсвующее поведение if ($width > $height) { $width = ceil($width-($width*($r-$target_width/$target_height))); } else { $height = ceil($height-($height*($r-$target_width/$target_height))); } $newwidth = $target_width; $newheight = $target_width; } else { if ($target_width/$target_height > $r) { $newwidth = $target_height*$r; $newheight = $target_height; } else { $newheight = $target_width/$r; $newwidth = $target_width; } } switch($mime['mime']) //проверяем тип картинки, ив зависимот=сти от этого изменяем функции генерации и экспорта картинки { case 'image/gif': $creationFunction = 'imagecreatefromgif'; //фунция генерации $outputFunction = 'imagepng'; //функция экспорта $mime = 'image/png'; // конвертируем gif в png $quality = round(10 - ($quality / 10)); // для png качество задается от 1 до 9, а не как в jpeg от 1 до 100 break; case 'image/x-png': case 'image/png': $creationFunction = 'imagecreatefrompng'; $outputFunction = 'imagepng'; $quality = round(10 - ($quality / 10)); break; default: $creationFunction = 'imagecreatefromjpeg'; $outputFunction = 'imagejpeg'; break; } $src = $creationFunction($original_image_path); $dst = imagecreatetruecolor($newwidth, $newheight); imagecopyresampled($dst, $src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height); //генерируем превью $outputFunction($dst, $new_path, $quality); //сохраняем на диск // Чистим память imagedestroy($src); imagedestroy($dst); echo $true_path; //возращаем путь относительно домена } } } </source >
ссылка на оригинал статьи http://habrahabr.ru/post/182592/
Добавить комментарий