CImageHandler - работа с изображениями
Re: CImageHandler - работа с изображениями
Открой само расширение и посмотри там метод thumb. Там можно увидеть, что он принимает и что делает.
Re: CImageHandler - работа с изображениями
В принципе, на данный момент я его не совершенствую...Понимаю, что последний ответ был довольно таки давно, но поддерживается ли еще разработка расширения.
На данный момент можно попробовать использовать методУ меня в процессе работы возник вопрос, можно ли в функцию ->thumb() передать один из параметров false, чтобы ресайз шел пропорционально, но только используя один из параметров функции? Т.е. если мне нужно, чтобы все загруженные фото были точно 200px по ширине, а высота не имеет значения.
Код: Выделить всё
public function resize($toWidth, $toHeight, $proportional = true)
Код: Выделить всё
resize(200, 1000000)
на выходных добавлю возможность указывать неограниченную высоту/ширину
Re: CImageHandler - работа с изображениями
Добавил возможность задавать неограниченную высоту/ширину для превюшек и ресайза а также более детальное описание методов класса.
Решил таки развивать класс, поэтому ждите версию 2.0 с серьезными улучшениями.
Решил таки развивать класс, поэтому ждите версию 2.0 с серьезными улучшениями.
Re: CImageHandler - работа с изображениями
Стал использовать ваше расширение! Спасибо!
В функции сохранения исправил выбор типа сохранения файлов в формат:
было:
В функции сохранения исправил выбор типа сохранения файлов в формат:
Код: Выделить всё
switch ($toFormat)
{
case 'IMG_GIF':
if (!imagegif($this->image, $file))
{
throw new Exception('Can\'t save gif file');
}
break;
case 'IMG_JPEG':
if (!imagejpeg($this->image, $file, $jpegQuality))
{
throw new Exception('Can\'t save jpeg file');
}
break;
case 'IMG_PNG':
if (!imagepng($this->image, $file))
{
throw new Exception('Can\'t save png file');
}
break;
default:
throw new Exception('Invalid image format for save');
}
Код: Выделить всё
switch ($toFormat)
{
case self::IMG_GIF:
if (!imagegif($this->image, $file))
{
throw new Exception('Can\'t save gif file');
}
break;
Re: CImageHandler - работа с изображениями
Константы лучше использовать, поскольку в случае неправильного написания интерпретатор выдаст ошибку, да и автодополнение работает...
Re: CImageHandler - работа с изображениями
Почему бы не выложить код на github, чтобы все смогли его дополнять?
github profile: https://github.com/kirs
Re: CImageHandler - работа с изображениями
Я уже давно планирую выложить этот (и остальные написанные мной компоненты, у меня их много) компонент в YiiExt репозиторий, но все не найду время на написание нормальной английской и русской документации... Через две недели у меня времени будет однозначно больше, поэтому займусь всем этим. Кроме того у меня на 80% готова вторая версия CImageHandler, думаю есть смысл выложить уже последнюю версию.
В любом случае код распространяется под свободной лицензией, поэтому Вы можете выложить его куда угодно самостоятельно, только сохраните, пожалуйста, авторство. Но я все равно считаю, что лучше когда один человек вносит правки в небольшие проекты, поэтому лучше будет если вы напишете замечание здесь
В любом случае код распространяется под свободной лицензией, поэтому Вы можете выложить его куда угодно самостоятельно, только сохраните, пожалуйста, авторство. Но я все равно считаю, что лучше когда один человек вносит правки в небольшие проекты, поэтому лучше будет если вы напишете замечание здесь
Re: CImageHandler - работа с изображениями
Добрый день, подскажите пожалуйста как сделать проверку на наличие файла?
Допустим есть массив с ссылками и соответствующий код:
Как прописать continue; в случае если ссылка битая и файл отсутствует?
Не откажите в помощи начинающему.
Допустим есть массив с ссылками и соответствующий код:
Код: Выделить всё
$i = 1;
foreach ($photos as $photo) {
Yii::app()->ih->load($photo)->resize(600, 450)->save($_SERVER['DOCUMENT_ROOT'] .
'/images/photo/' . $i . '.jpg');
$i++;
}
Не откажите в помощи начинающему.
- usualdesigner
- Сообщения: 119
- Зарегистрирован: 2011.08.08, 13:23
- Откуда: Киев, Украина
- Контактная информация:
Re: CImageHandler - работа с изображениями
Вот у автора для сорса изображения можно указать как полный серверный путь, так и URL. В чистом GD или ImageMagic можно делать также, или там нужно именно серверный путь скармливать сорсу?
- usualdesigner
- Сообщения: 119
- Зарегистрирован: 2011.08.08, 13:23
- Откуда: Киев, Украина
- Контактная информация:
Re: CImageHandler - работа с изображениями
И еще возникло несколько вопросов по расширению:
1. Как залить фон у изображения с сохранением оригинального размера?
2. При рендере исходного изображения (png) с прозрачным фоном получаю вместо прозрачного черный фон с какими то артефактами.
1. Как залить фон у изображения с сохранением оригинального размера?
2. При рендере исходного изображения (png) с прозрачным фоном получаю вместо прозрачного черный фон с какими то артефактами.
Код: Выделить всё
Yii::app()->ih
->load($image->fullPath)
->show();
- Вложения
-
- index.php.png (209.66 КБ) 10552 просмотра
Re: CImageHandler - работа с изображениями
Все хорошо, но качество полученных картинок очень плохое. С чем может быть связано, как исправить?
Re: CImageHandler - работа с изображениями
Тоже с этим столкнулся, судя по всему это из-за jpeg. По умолчанию изображения сжимаются до 75% качества
Код: Выделить всё
public function save($file = false, $toFormat = false, $jpegQuality = 75, $touch = false)
Re: CImageHandler - работа с изображениями
Автор проделал хорошую работу, молодец!
Данное решение может быть полезно в случае когда imageMagic использовать нет возможности.
Данное решение может быть полезно в случае когда imageMagic использовать нет возможности.
-
- Сообщения: 21
- Зарегистрирован: 2011.09.21, 15:34
Re: CImageHandler - работа с изображениями
спасибо за полезный код
ждем кеширование
ну например чтото типа из скрипта image-crop.php
// Smart Image Resizer 1.4.1
// Resizes images, intelligently sharpens, crops based on width:height ratios, color fills
// transparent GIFs and PNGs, and caches variations for optimal performance
// Created by: Joe Lencioni (http://shiftingpixel.com)
// Date: August 6, 2008
// Based on: http://veryraw.com/history/2005/03/imag ... -with-php/
ждем кеширование
ну например чтото типа из скрипта image-crop.php
// Smart Image Resizer 1.4.1
// Resizes images, intelligently sharpens, crops based on width:height ratios, color fills
// transparent GIFs and PNGs, and caches variations for optimal performance
// Created by: Joe Lencioni (http://shiftingpixel.com)
// Date: August 6, 2008
// Based on: http://veryraw.com/history/2005/03/imag ... -with-php/
Re: CImageHandler - работа с изображениями
Здравствуйте!
Заметил, что resizeCanvas немного некорректно вычисляет новые размеры картинки, в результате чего картинки некоторых размеров оказываются обрезанными. Немного модернизировал метод:
Теперь преобразование размера зависит не только от того, вертикальная картинка или горизонтальная (предыдущий вариант преобразования):
Теперь для преобразования вычисляются коэффициенты (исходя из соотношений сторон), и умножение производится на меньший коэффициент, т. е. картинка гарантированно полностью попадет в заданную область:
Досконально не тестил, но вроде работает корректно
Заметил, что resizeCanvas немного некорректно вычисляет новые размеры картинки, в результате чего картинки некоторых размеров оказываются обрезанными. Немного модернизировал метод:
Код: Выделить всё
public function resizeCanvas($toWidth, $toHeight, $backgroundColor = array(255, 255, 255))
{
$this->checkLoaded();
$newWidth = min($toWidth, $this->width);
$newHeight = min($toHeight, $this->height);
$koef_w=$newWidth / $this->width;
$koef_h=$newHeight / $this->height;
if ($koef_w < $koef_h)
{
$newHeight = round($koef_w * $this->height);
}
else
{
$newWidth = round($koef_h * $this->width);
}
$posX = floor(($toWidth - $newWidth) / 2);
$posY = floor(($toHeight - $newHeight) / 2);
$newImage = imagecreatetruecolor($toWidth, $toHeight);
$backgroundColor = imagecolorallocate($newImage, $backgroundColor[0], $backgroundColor[1], $backgroundColor[2]);
imagefill($newImage, 0, 0, $backgroundColor);
imagecopyresampled($newImage, $this->image, $posX, $posY, 0, 0, $newWidth, $newHeight, $this->width, $this->height);
imagedestroy($this->image);
$this->image = $newImage;
$this->width = $toWidth;
$this->height = $toHeight;
return $this;
}
Код: Выделить всё
if ($this->width > $this->height)
{
$newHeight = round($newWidth / $this->width * $this->height);
}
else
{
$newWidth = round($newHeight / $this->height * $this->width);
}
Код: Выделить всё
$koef_w=$newWidth / $this->width;
$koef_h=$newHeight / $this->height;
if ($koef_w < $koef_h)
{
$newHeight = round($koef_w * $this->height);
}
else
{
$newWidth = round($koef_h * $this->width);
}
Re: CImageHandler - работа с изображениями
Добрый день. А где его возможно скачать. Поделитесь ссылкой пожалуйста.
Re: CImageHandler - работа с изображениями
В начальных каментах к посту есть ссылки.setrais писал(а):Добрый день. А где его возможно скачать. Поделитесь ссылкой пожалуйста.
Re: CImageHandler - работа с изображениями
Автор, не кажется ли вам, что реализованный вами метод reload() уж слишком ресурсоёмкий?
Картинка каждый раз уничтожается в памяти! И снова распаковывается в память из файла!
Это ресурсоёмко! Решение помоему очевидно!
Пришлось немного изменить ваш класс.
1) Была произведена замена всего private на protected (дабы устранить проблемы наследования);
2) Вызов imagedestroy($this->image) в функциях был заменён на $this->freeImage(); - Это производит абсолютно тотже самый эффект, но в наследуемом классе изменена логика freeImage(), дабы убить сразу двух зайцев:
1) сохранить первоначальную логику работы вашего класса;
2) обеспечить корректную работу старых непереопределённых методов с новой логикой reload()! (не тестил, но проблем быть не должно)
1) добавил 3 новых protected свойства с префиксом old, для хранения состояния первоначально загруженного изображения.
2) Переопределил методы
__destruct(),
freeImage(),
load(),
reload(),
resize(). (по сути мне был нужен только этот метод, его также использует thumb)
3) Добавил методы
createImage(). - корректно создает пустое рабочее изображение для дальнейших манипуляций.
resizeCanvas(). - код скопипастил из сообщения выше по теме.
grayScale(). - теперь изображение можно делать чёрно-белым.
Теперь в изображениях, которые были созданы из исходников c прозрачностью, нет артефактов (вложил пример, созданный из png с alpha-каналом)!!! (протестировано для методов thumb() и соответственно resize())
Вкладываю архив с файлами классов. Первоначальный класс немного изменён, но логика работы осталась нетронутой!
Не советую сливать всё в 1 класс, используйте лучше наследование, если вы не целиком понимаете, что вы делаете. Также вы всегда сможете вернуться к первоначальной реализации. Но для использования новых возможностей наследуемого класса, замена файла с исходным классом обязательна!
Картинка каждый раз уничтожается в памяти! И снова распаковывается в память из файла!
Это ресурсоёмко! Решение помоему очевидно!
Пришлось немного изменить ваш класс.
1) Была произведена замена всего private на protected (дабы устранить проблемы наследования);
2) Вызов imagedestroy($this->image) в функциях был заменён на $this->freeImage(); - Это производит абсолютно тотже самый эффект, но в наследуемом классе изменена логика freeImage(), дабы убить сразу двух зайцев:
1) сохранить первоначальную логику работы вашего класса;
2) обеспечить корректную работу старых непереопределённых методов с новой логикой reload()! (не тестил, но проблем быть не должно)
Код: Выделить всё
<?php
class ImageHandler extends CImageHandler
{
protected $oldImage;
protected $oldWidth;
protected $oldHeight;
protected $trueColor=null;
public function __destruct()
{
parent::__destruct();
if(is_resource($this->oldImage))
imagedestroy($this->oldImage);
}
protected function freeImage()
{
if($this->image!==$this->oldImage)
parent::freeImage();
}
protected function createImage($width,$height,$trueColor=null)
{
$Image=null;
if(is_null($trueColor)){
if(function_exists('ImageIsTrueColor'))
$createTrueColor=ImageIsTrueColor($this->image);
else
$createTrueColor=true;
} else {
$createTrueColor=$trueColor;
}
if($createTrueColor && function_exists('ImageCreateTrueColor'))
$Image=@ImageCreateTrueColor($width, $height);
if(is_null($Image)){
$Image=ImageCreate($width,$height);
imagepalettecopy($Image,$this->image);
$color=imagecolortransparent($this->image);
if ($color!=-1) {
imagecolortransparent($Image,$color);
imagefill($Image,0,0,$color);
}
}
return $Image;
}
public function load($file)
{
if(!parent::load($file))
return false;
$this->oldImage=$this->image;
$this->oldWidth=$this->width;
$this->oldHeight=$this->height;
return $this;
}
public function reload()
{
$this->freeImage();
if(!is_resource($this->oldImage))
throw new CException('Can\'t reload.');
$this->image=$this->oldImage;
$this->width=$this->oldWidth;
$this->height=$this->oldHeight;
return $this;
}
public function resize($toWidth,$toHeight,$proportional=true)
{
$this->checkLoaded();
$toWidth = $toWidth !== false ? $toWidth : $this->width;
$toHeight = $toHeight !== false ? $toHeight : $this->height;
if($proportional)
{
$newHeight = $toHeight;
$newWidth = round($newHeight / $this->height * $this->width);
if($newWidth > $toWidth)
{
$newWidth = $toWidth;
$newHeight = round($newWidth / $this->width * $this->height);
}
}
else
{
$newWidth = $toWidth;
$newHeight = $toHeight;
}
$newImage=$this->createImage($newWidth,$newHeight,$this->trueColor);
$icrRes=null;
if(function_exists('ImageCopyResampled'))
$icrRes=ImageCopyResampled($newImage,$this->image,0,0,0,0,$newWidth,$newHeight,$this->width,$this->height);
if(is_null($icrRes))
ImageCopyResized($newImage,$this->image,0,0,0,0,$newWidth,$newHeight,$this->width,$this->height);
$this->freeImage();
$this->image=$newImage;
$this->width=$newWidth;
$this->height=$newHeight;
return $this;
}
public function resizeCanvas($toWidth, $toHeight, $backgroundColor = array(255, 255, 255))
{
$this->checkLoaded();
$newWidth = min($toWidth, $this->width);
$newHeight = min($toHeight, $this->height);
$c_w=$newWidth / $this->width;
$c_h=$newHeight / $this->height;
if ($c_w < $c_h)
{
$newHeight = round($c_w * $this->height);
}
else
{
$newWidth = round($c_h * $this->width);
}
$posX = floor(($toWidth - $newWidth) / 2);
$posY = floor(($toHeight - $newHeight) / 2);
$newImage=$this->createImage($toWidth,$toHeight,$this->trueColor);
$backgroundColor = imagecolorallocate($newImage, $backgroundColor[0], $backgroundColor[1], $backgroundColor[2]);
imagefill($newImage, 0, 0, $backgroundColor);
imagecopyresampled($newImage, $this->image, $posX, $posY, 0, 0, $newWidth, $newHeight, $this->width, $this->height);
$this->freeImage();
$this->image = $newImage;
$this->width = $toWidth;
$this->height = $toHeight;
return $this;
}
public function grayScale()
{
$newImage=$this->createImage($this->width,$this->height,$this->trueColor);
imagecopy($newImage,$this->image,0,0,0,0,$this->width,$this->height);
imagecopymergegray($newImage,$newImage,0,0,0,0,$this->width,$this->height,0);
$this->freeImage();
$this->image=$newImage;
return $this;
}
}
2) Переопределил методы
__destruct(),
freeImage(),
load(),
reload(),
resize(). (по сути мне был нужен только этот метод, его также использует thumb)
3) Добавил методы
createImage(). - корректно создает пустое рабочее изображение для дальнейших манипуляций.
resizeCanvas(). - код скопипастил из сообщения выше по теме.
grayScale(). - теперь изображение можно делать чёрно-белым.
Теперь в изображениях, которые были созданы из исходников c прозрачностью, нет артефактов (вложил пример, созданный из png с alpha-каналом)!!! (протестировано для методов thumb() и соответственно resize())
Вкладываю архив с файлами классов. Первоначальный класс немного изменён, но логика работы осталась нетронутой!
Не советую сливать всё в 1 класс, используйте лучше наследование, если вы не целиком понимаете, что вы делаете. Также вы всегда сможете вернуться к первоначальной реализации. Но для использования новых возможностей наследуемого класса, замена файла с исходным классом обязательна!
- Вложения
-
- CImageHandler.rar
- (3.07 КБ) 267 скачиваний
-
- изображение без артефактов
- scam_normal.jpg (6.07 КБ) 10315 просмотров
-
- изображение с артефактами
- scam_artefacts.jpg (6.22 КБ) 10315 просмотров
Re: CImageHandler - работа с изображениями
Да в чистом GD можно напрямую (нужны также соотв. настройки PHP). Для ImageMagic через fopen http://php.net/manual/en/imagick.readimagefile.phpusualdesigner писал(а):Вот у автора для сорса изображения можно указать как полный серверный путь, так и URL. В чистом GD или ImageMagic можно делать также, или там нужно именно серверный путь скармливать сорсу?
Такой функционал пока не предусмотрен. Очень не элегантный воркараунд это сделать resizeCanvas указав исходный размер изображения.usualdesigner писал(а):1. Как залить фон у изображения с сохранением оригинального размера?
У самого GD есть проблемы с прозрачностью PNG. Для фикса создан метод preserveTransparency. Если показывать изображение без какой-либо обработки как в Вашем случае, то этот метод не вызывается.usualdesigner писал(а):2. При рендере исходного изображения (png) с прозрачным фоном получаю вместо прозрачного черный фон с какими то артефактами.
Код: Выделить всё
Yii::app()->ih ->load($image->fullPath) ->show();
phillip писал(а):Все хорошо, но качество полученных картинок очень плохое. С чем может быть связано, как исправить?
Да, просто увеличите качество в соотв. параметре. Меня устраивало 75 по качеству/весу изображения для превюшек, поэтому оставил это значение по умолчанию.nidkor писал(а):Тоже с этим столкнулся, судя по всему это из-за jpeg. По умолчанию изображения сжимаются до 75% качестваКод: Выделить всё
public function save($file = false, $toFormat = false, $jpegQuality = 75, $touch = false)
Спасибо!cioxideru писал(а):Автор проделал хорошую работу, молодец!
Данное решение может быть полезно в случае когда imageMagic использовать нет возможности.
Спасибо!alisherdavronov писал(а):спасибо за полезный код
ждем кеширование
Спасибо! Это у меня пофикшено в новой версии, которую все не дойдут руки привести в нормальный вид (добавил ссылку в первый пост).HotAlex писал(а):Здравствуйте!
Заметил, что resizeCanvas немного некорректно вычисляет новые размеры картинки, в результате чего картинки некоторых размеров оказываются обрезанными. Немного модернизировал метод:
Sc@M Спасибо за критику! Обещаю что на этой неделе внесу правки в код (пока добавил ссылку на Ваше сообщение в первый пост).