CImageHandler - работа с изображениями

Выкладываем свои наработки
Аватара пользователя
Tokolist
Сообщения: 113
Зарегистрирован: 2010.03.01, 22:03

Re: CImageHandler - работа с изображениями

Сообщение Tokolist »

wa1demar где добавлять код использования компонента зависит от логики вашего приложения, Вам, скорей всего, нужно добавить его в экшн, но точно не в behaviors. Компонент с базой не работает, Вам необходимо реализовать обновление базы самостоятельно. Имя файла можно задать в методе save(), либо оставить пустым и тогда оригинальный файл будет затерт (в ридми это указанно).
oki84
Сообщения: 72
Зарегистрирован: 2011.08.01, 14:09

Re: CImageHandler - работа с изображениями

Сообщение oki84 »

Здравствуйте! Во-первых огромное спасибо за Ваш труд, обыскался быстрое расширение для работы с изображениями да ещё и с возможностью вотермарков!
Попробовал Ваше, быстро и просто.
Но возникло затруднение с вотермарками, у меня лежит вотермарк в конкретном(большом - логотип) разрешении, а по сайту используются и создаются изображения различного разрешения и держать под каждое из них свой вотермарк трудоёмко и глупо. Поэтому предлагаю немного расширить функционал в отношении вотермарков и добавить пару параметров. Не судите строго я не профессионал, любой критике буду рад, вот что получилось:

Код: Выделить всё

    public function watermark($watermarkFile, $offsetX, $offsetY, $corner = self::CORNER_RIGHT_BOTTOM, $autoZoom = true, $zoomPercent = 30)
    {

        $this->checkLoaded();

        if ($wImg = $this->loadImage($watermarkFile))
        {
            $posX = 0;
            $posY = 0;
if ($autoZoom)
{
    $oldwImgWidth       =   $wImg['width'];
    $oldwImgHeight      =   $wImg['height'];
    $wImg['width']      =   floor($this->width    * $zoomPercent  /   100);
    $wImg['height']     =   floor($wImg['width']  * $oldwImgHeight  /   $oldwImgWidth);
}
            switch ($corner)
            {
                case self::CORNER_LEFT_TOP:
                    $posX = $offsetX;
                    $posY = $offsetY;
                    break;
                case self::CORNER_RIGHT_TOP:
                    $posX = $this->width - $wImg['width'] - $offsetX;
                    $posY = $offsetY;
                    break;
                case self::CORNER_LEFT_BOTTOM:
                    $posX = $offsetX;
                    $posY = $this->height - $wImg['height'] - $offsetY;
                    break;
                case self::CORNER_RIGHT_BOTTOM:
                    $posX = $this->width - $wImg['width'] - $offsetX;
                    $posY = $this->height - $wImg['height'] - $offsetY;
                    break;
                case self::CORNER_CENTER:
                    $posX = floor(($this->width - $wImg['width']) / 2);
                    $posY = floor(($this->height - $wImg['height']) / 2);
                    break;
                default:
                    throw new Exception('Invalid $corner value');
            }

if($autoZoom)
{
    imagecopyresampled($this->image, $wImg['image'], $posX, $posY, 0, 0, $wImg['width'], $wImg['height'], $oldwImgWidth, $oldwImgHeight);
}
else
{
    imagecopy($this->image, $wImg['image'], $posX, $posY, 0, 0, $wImg['width'], $wImg['height']);
}
            


            imagedestroy($wImg['image']);

            return $this;
        }
        else
        {
            return false;
        }
    }


Моё творчество неоттабулированно. Как видно из названий переменных $autoZoom - это указание на автоматический ресайз под итоговое изображение, а $zoomPercent - это количество процентов от ширины нового изображения, которое и определяет размер вотермарка после его ресайза(вотермарк ресайзится пропорционально).
Аватара пользователя
Tokolist
Сообщения: 113
Зарегистрирован: 2010.03.01, 22:03

Re: CImageHandler - работа с изображениями

Сообщение Tokolist »

oki84 спасибо! обновил компонент.
v0lume
Сообщения: 13
Зарегистрирован: 2012.06.04, 14:21

Re: CImageHandler - работа с изображениями

Сообщение v0lume »

сегодня столкнулся с такой вот ерундой...наложил watermark
в чем проблема?
Изображение

извиняюсь за слона



самое интересное, что такое случается только тогда, когда точка наложения - темная (серая\черная)
если в этой точке другие цвета - всё отлично накладывается
v0lume
Сообщения: 13
Зарегистрирован: 2012.06.04, 14:21

Re: CImageHandler - работа с изображениями

Сообщение v0lume »

частично убираются артефакты путем добавления $this->preserveTransparency($wImg['image']);

но всё равно не полностью

Код: Выделить всё

    public function watermark($watermarkFile, $offsetX, $offsetY, $corner = self::CORNER_RIGHT_BOTTOM, $zoom = false)
    {

        $this->checkLoaded();

        if ($wImg = $this->loadImage($watermarkFile))
        {

            $posX = 0;
            $posY = 0;
                        
            $watermarkWidth = $wImg['width'];
            $watermarkHeight = $wImg['height'];

            if($zoom !== false)
            {
                $dimension = round(max($this->width, $this->height) * $zoom);

                $watermarkHeight = $dimension;
                $watermarkWidth = round($watermarkHeight / $wImg['height'] * $wImg['width']);

                if($watermarkWidth > $dimension)
                {
                    $watermarkWidth = $dimension;
                    $watermarkHeight = round($watermarkWidth / $wImg['width'] * $wImg['height']);
                }
            }

            switch ($corner)
            {
                case self::CORNER_LEFT_TOP:
                    $posX = $offsetX;
                    $posY = $offsetY;
                    break;
                case self::CORNER_RIGHT_TOP:
                    $posX = $this->width - $watermarkWidth - $offsetX;
                    $posY = $offsetY;
                    break;
                case self::CORNER_LEFT_BOTTOM:
                    $posX = $offsetX;
                    $posY = $this->height - $watermarkHeight - $offsetY;
                    break;
                case self::CORNER_RIGHT_BOTTOM:
                    $posX = $this->width - $watermarkWidth - $offsetX;
                    $posY = $this->height - $watermarkHeight - $offsetY;
                    break;
                case self::CORNER_CENTER:
                    $posX = floor(($this->width - $watermarkWidth) / 2);
                    $posY = floor(($this->height - $watermarkHeight) / 2);
                    break;
                default:
                    throw new Exception('Invalid $corner value');
            }
            $this->preserveTransparency($wImg['image']);
            imagecopyresampled(
                $this->image,
                $wImg['image'],
                $posX,
                $posY,
                0,
                0,
                $watermarkWidth,
                $watermarkHeight,
                $wImg['width'],
                $wImg['height']
            );


            imagedestroy($wImg['image']);

            return $this;
        }
        else
        {
            return false;
        }
    } 
Аватара пользователя
Tokolist
Сообщения: 113
Зарегистрирован: 2010.03.01, 22:03

Re: CImageHandler - работа с изображениями

Сообщение Tokolist »

попробуйте изменить следующее свойство

Код: Выделить всё

public $transparencyColor = array(0, 0, 0); 
если не помогает, мне нужны будут оригиналы изображений, чтобы воссоздать проблему
YunX
Сообщения: 87
Зарегистрирован: 2011.07.06, 12:53

Re: CImageHandler - работа с изображениями

Сообщение YunX »

Проблема с прозрачным фоном наблюдается при наложении водяного знакак на изображение формата .png
Аватара пользователя
Tokolist
Сообщения: 113
Зарегистрирован: 2010.03.01, 22:03

Re: CImageHandler - работа с изображениями

Сообщение Tokolist »

Нужны обе картинки (изображение и вотермарк) для воссоздания проблемы. Можно в личные сообщения.
d4rkr00t
Сообщения: 15
Зарегистрирован: 2010.09.03, 20:27

Re: CImageHandler - работа с изображениями

Сообщение d4rkr00t »

Фиксил проблему в одном проекте, правда уже не помню что и как, такой метод должен работать:

Код: Выделить всё

public function watermark($watermarkFile, $offsetX, $offsetY, $corner = self::CORNER_RIGHT_BOTTOM)
    {

        $this->checkLoaded();

        if ($wImg = $this->loadImage($watermarkFile))
        {

            $posX = 0;
            $posY = 0;

            switch ($corner)
            {
                case self::CORNER_LEFT_TOP:
                    $posX = $offsetX;
                    $posY = $offsetY;
                    break;
                case self::CORNER_RIGHT_TOP:
                    $posX = $this->width - $wImg['width'] - $offsetX;
                    $posY = $offsetY;
                    break;
                case self::CORNER_LEFT_BOTTOM:
                    $posX = $offsetX;
                    $posY = $this->height - $wImg['height'] - $offsetY;
                    break;
                case self::CORNER_RIGHT_BOTTOM:
                    $posX = $this->width - $wImg['width'] - $offsetX;
                    $posY = $this->height - $wImg['height'] - $offsetY;
                    break;
                case self::CORNER_CENTER:
                    $posX = floor(($this->width - $wImg['width']) / 2);
                    $posY = floor(($this->height - $wImg['height']) / 2);
                    break;
                default:
                    throw new Exception('Invalid $corner value');
            }
            
            $trans = imagecolorallocate($wImg['image'], 0, 0, 0);
            imagecolortransparent($wImg['image'],$trans);

            $newImage = imagecreatetruecolor($this->width, $this->height);
            imagecopy($newImage, $this->image, 0, 0, 0, 0, $this->width, $this->height);

            $this->image = $newImage;

            imagecopy($this->image, $wImg['image'], $posX, $posY, 0, 0, $wImg['width'], $wImg['height']);

            imagedestroy($wImg['image']);

            return $this;
        }
        else
        {
            return false;
        }
    }
Аватара пользователя
Tokolist
Сообщения: 113
Зарегистрирован: 2010.03.01, 22:03

Re: CImageHandler - работа с изображениями

Сообщение Tokolist »

YunX Протестировал различные комбинации форматов JPEG, GIF и PNG. Проблемы наблюдаются только при наложении GIF на PNG, PNG на GIF и JPEG на GIF, пока не придумал как это фиксить (скорей всего GIF надо будет приводить к PNG для сохранения прозрачности и цветов, плюс сохранять надо будет тоже в PNG). Вряд ли кому-то придется использовать указанные комбинации изображений, но попробую найти решение проблемы, т.к. пока руки не доходят написать ImageMagic версию (теоретически там таких проблем не должно быть).

Если у вас наблюдаются проблемы наложения других форматов, то убедитесь, что вы используете последнюю версию компонента и отправьте мне обе картинки для воссоздания проблемы.
Аватара пользователя
Tokolist
Сообщения: 113
Зарегистрирован: 2010.03.01, 22:03

Re: CImageHandler - работа с изображениями

Сообщение Tokolist »

d4rkr00t Спасибо, посмотрю ваш код.
Аватара пользователя
Koduc
Сообщения: 140
Зарегистрирован: 2011.02.15, 18:56

Re: CImageHandler - работа с изображениями

Сообщение Koduc »

Спасибо за полезный компонент!
Сделал pull-request:
1) добавил дополнительные позиции для водяного знака и текста;
2) добавил alpha для метода text(), т.е. текст теперь можно выводить с различный уровнем прозрачности (0 - обычный, 127 - полностью прозрачный);

Думаю полезные будут фичи для нанесения ватермарков.
Разработка на Yii: monoray.ru
Открытое бесплатное решение для создания сайтов по аренде/продаже недвижимости: Open Real Estate
Аватара пользователя
Tokolist
Сообщения: 113
Зарегистрирован: 2010.03.01, 22:03

Re: CImageHandler - работа с изображениями

Сообщение Tokolist »

Большое спасибо! Обновил код.
Zdraff
Сообщения: 23
Зарегистрирован: 2013.01.30, 17:16

Re: CImageHandler - работа с изображениями

Сообщение Zdraff »

Tokolist, Вы прелесть) Только собрался писать компонент, случайно наткнулся на Ваш. Оказалось, все уже написано до нас, что нужно) Спасибо.
Woice
Сообщения: 9
Зарегистрирован: 2012.07.26, 11:34

Re: CImageHandler - работа с изображениями

Сообщение Woice »

Tokolist писал(а): В планах на будущее:
3. обертка над ImageMagic, с возможностью переключения между GD и ImageMagic (хотя не уверен что есть такая необходимость)
Хотелось бы узнать. Когда вы примерно собираетесь сделать это? Думаю сам писать, но может и нет смысла спешить =).
А насчет необходимости могу отметить как раз, что есть ситуации, при которых это нужно.

У меня такая ситуация сложилась: GD почему-то выдает после кропа или ресайза другие цвета. ImageMagick такого, почему-то не делает - никаких проблем. + проблема с загрузкой больших файлов на ImageMagick как-то проще решается =).
Аватара пользователя
Tokolist
Сообщения: 113
Зарегистрирован: 2010.03.01, 22:03

Re: CImageHandler - работа с изображениями

Сообщение Tokolist »

На данный момент, к сожалению, нету времени развивать компонент и пока не знаю когда появится. По сути все что есть это пункт в TODO и некоторые наброски структуры, которые не вижу смысла выкладывать.

Если напишете аналог на ImageMagic, будет здорово объединить наши коды в один продукт.
Аватара пользователя
yiijeka
Сообщения: 3103
Зарегистрирован: 2012.01.28, 09:14
Откуда: Беларусь
Контактная информация:

Re: CImageHandler - работа с изображениями

Сообщение yiijeka »

Подскажите, есть ли возможность найти на чёрно-белой картинке (схеме) КООРДИНАТЫ определённого текста? Какими средствами, это можно сделать?
Аватара пользователя
kosenka
Сообщения: 677
Зарегистрирован: 2009.09.26, 12:41
Откуда: москва
Контактная информация:

Re: CImageHandler - работа с изображениями

Сообщение kosenka »

Сделал pull-request:
добавил поддержку ImageMagick
Аватара пользователя
Tokolist
Сообщения: 113
Зарегистрирован: 2010.03.01, 22:03

Re: CImageHandler - работа с изображениями

Сообщение Tokolist »

kosenka Большое спасибо! Посмотрю в ближайшее время.
Аватара пользователя
Tokolist
Сообщения: 113
Зарегистрирован: 2010.03.01, 22:03

Re: CImageHandler - работа с изображениями

Сообщение Tokolist »

kosenka, еще раз спасибо за код. это хороший пинок мне чтобы допилить компонент :) создал отдельную ветку в репозитории, т.к. есть несколько идей по улучшению кода.
Ответить