PHP Image Workshop: простая работа с изображениями как со слоями

Какие задачи по обработке картинок на php чаще всего стоят перед нами? Как правило, это изменение размера изображений, их кадрирование, наложение водяных знаков и надписей, поворот, изменение формата. В поисках лучшей библиотеки для работы с изображениями на php я перепробовал немало готовых решений, и даже начинал писать своё. Не так давно я наткнулся на библиотеку под названием PHP Image Workshop - PHP класс, использующий библиотеку gd, позволяющий работать с изображениями как со слоями (по аналогии с известными программами Photoshop и GIMP). Звучит неплохо, да? Вот и я решил попробовать.


PHP Image Workshop

Разработчики PHP Image Workshop предлагают использовать принцип построения изображения из слоёв, являющихся php объектами, которые можно делить на группы, перемещать, вращать, накладывать и объединять. Сегодня я расскажу как подключить этот класс в свой скрипт, а так же покажу простой пример построения коллажа с его помощью.

Подключение РHP Image Workshop

Скачиваем последнюю версию (на текущий момент это версия 2.0) c сайта разработчика, выгружаем на сервер папку /src/PHPImageWorkshop из архива. Теперь, в зависимости от версии php, типа скрипта, знаний и количества свободного времени, выбираем один из вариантов.

У меня php 5.3+ и используется автозагрузчик классов

Великолепно! Разработчики Image Workshop, за что им честь и хвала, использовали технологию пространств имён (namespaces). Осталось только расположить папку PHPImageWorkshop в директорию с библиотеками, с которой работает автолоадер.

К примеру, чтобы подключить PHP Image Workshop к Yii Framework, нужно загрузить её в директорию расширений (обычно это /protected/extensions) и добавить в action пару строк кода:


// Импорт класса
Yii::import('ext.PHPImageWorkshop.*');

// Создание простанства имён PHPImageWorkshop
Yii::setPathOfAlias('PHPImageWorkshop', Yii::getPathOfAlias('ext.PHPImageWorkshop').'/');
                    

У меня php 5.3+ и я знать не хочу ни про какие автозагрузчики

Проще было узнать об автозагрузке, но, раз на то пошло, такой вариант тоже предусмотрен. Нужно один за другим, во всех подпапках открыть файлы классов библиотеки и раскомментировать вызов //require_once() в начале каждого файла. Вот пример:


// ImageWorkshop.php, строка 9:
 
// If no autoloader, uncomment these lines:
require_once(__DIR__.'/Core/ImageWorkshopLayer.php');
require_once(__DIR__.'/Exception/ImageWorkshopException.php');
                    

После этого нужно подключить файл главного класса ImageWorkshop в коде своего скрипта:


// path/to/lib/ - путь до директории с PHPImageWorkshop на сервере
require_once('path/to/lib/PHPImageWorkshop/ImageWorkshop.php');
                    

У меня php 5.2 или ниже

Не завидую :( Можно сплясать и поудалять все вкрапления namespaces из всех классов библиотеки. Инструкции можно найти тут, но проще обновить php.

Использование PHP Image Workshop

Есть два варианта использовать класс Image Workshop. Первый - создать псевдоним для имени класса ImageWorkshop и обращаться к этому псевдониму:


// Использование псевдонима ImageWorkshop для обращения к PHPImageWorkshop\ImageWorkshop
use PHPImageWorkshop\ImageWorkshop; 
$mainLayer = ImageWorkshop::initXXX(...);
                    

Второй вариант - каждый раз прописывать путь до класса вместе с пространством имён (для меня удобен именно он):


$mainLayer = PHPImageWorkshop\ImageWorkshop::initXXX(...);
                    

Инициализация слоя


/**
 * Создание слоя из изображения
 * @param string $path - путь к изображению (или $_FILES["postName"]["tmp_name"] при загрузке файла)
 */
$mainLayer = PHPImageWorkshop\ImageWorkshop::initFromPath($path);
                    

Наложение слоёв


/**
 * Наложение слоя $layer поверх слоя $mainLayer
 * @param ImageWorkshop $layer - накладываемый слой
 * @param integer $positionX   - координата по оси X
 * @param integer $positionY   - координата по оси Y
 * @param string $position     - позиция (см. схему)
 */
$mainLayer->addLayerOnTop($layer, $positionX, $positionY, $position);
                    

Изменение размера слоя


/**
* Изменение размера слоя в пикселях
* @param integer $newWidth           - ширина
* @param integer $newHeight          - высота
* @param boolean $converseProportion - сохранение пропорций
* @param integer $positionX          - координата по оси X
* @param integer $positionY          - координата по оси Y
* @param string $position            - позиция (см. схему)
*/
$mainLayer->resizeInPixel($newWidth, $newHeight, $converseProportion, $positionX, $positionY, $position);
                    

Поворот слоя



/**
 * Поворот (в градусах)
 * @param float $degrees - угол поворота
 */
$mainLayer->rotate($degrees);
                    

Создание и добавление текстового слоя


/**
 * Создание текстового слоя
 * @param string $text              - текст
 * @param string $fontPath          - путь к файлу со шрифтом
 * @param integer $fontSize         - размер шрифта
 * @param string $fontColor         - цвет шрифта
 * @param integer $textRotation     - угол поворота текста (в градусах)
 * @param integer $backgroundColor  - цвет фона текста
 */
$textLayer = PHPImageWorkshop\ImageWorkshop::initTextLayer($text, $fontPath, $fontSize, $fontColor, $textRotation, $backgroundColor);
$mainLayer->addLayerOnTop($textLayer, $positionX, $positionY, $position);
                    

Сохранение изображения


/**
 * Сохраняет изображение по указанному пути
 * @param string $folder            - директория для сохраняемого изображения
 * @param string $imageName         - имя файла
 * @param boolean $createFolders    - создание папок, если таковых нет
 * @param string $backgroundColor   - цвет фона
 * @param integer $imageQuality     - качество изображения
 */
$mainLayer->save($folder, $imageName, $createFolders, $backgroundColor, $imageQuality);
                    

Отображение сформированного изображения


/**
 * Возвращает gd-resource из изображения
 * @param string $backgroundColor - цвет фона
 */
$image = $mainLayer->getResult($backgroundColor);
header('Content-type: image/jpeg');
header('Content-Disposition: filename="collage.jpg"');
imagejpeg($image, null, $quality);
exit;
                    

Позиционирование

В некоторых методах PHP Image Workshop позиционирование и точка отсчёта кординат определяется строкой $position, состоящей из двух букв. На схеме ниже показаны все возможные варианты позиционирования. Стрелки указывают направление, в котором будут отсчитываться координаты в случае указания той или иной позиции:

Позиции PHP Image Workshop

Пример использования PHP Image Workshop для создания коллажа

Представим, что нам нужно сделать модный коллаж. У нас есть фон collageBackground.jpg:

Фон для коллажа

На этот фон нужно наложить, уменьшив размер и повернув, 4 фотографии одежды collageImage1.jpg...collageImage4.jpg:

Изображения  для коллажа

Затем, поверх фотографий, нужно наложить такую вот маску collageMask.png, а поверх - написать цену 6 296 руб. Для добавления надписей потребуется файл шрифта. В данном случае - OpenSans-Bold.ttf:

Маска для коллажа

Вот, собственно, сам код для создания коллажа:


// Настройки
$imagePath = 'path/to/images'; // путь до папки с исходными изображениями и шрифтами
$quality   = 95;               // качество изображения создаваемого коллажа

// Создание базового слоя с фоном
$mainLayer = PHPImageWorkshop\ImageWorkshop::initFromPath($imagePath.'/collageBackground.jpg');

// Создание слоя с первым изображением
$imageLayer1 = PHPImageWorkshop\ImageWorkshop::initFromPath($imagePath.'/collageImage1.jpg');
// Ресайз картинки на первом слое
$imageLayer1->resizeInPixel(180, null, true);
// Поворот картинки на первом слое
$imageLayer1->rotate(-15);
// Добавление первого слоя поверх основного слоя с фоном
$mainLayer->addLayerOnTop($imageLayer1, 105, 145, "LT");

// То же самое со вторым, третьим и четвёртым изображениями, меняя углы поворота и координаты
// ...

// Добавляем слой с маской
$maskLayer = PHPImageWorkshop\ImageWorkshop::initFromPath($imagePath.'/collageMask.png');
$mainLayer->addLayerOnTop($maskLayer, 0, 0, "LT");

// Добавление текстового слоя с ценой:
$textSumLayer = PHPImageWorkshop\ImageWorkshop::initTextLayer('6 296', $imagePath.'/OpenSans-Bold.ttf', 20, "FFFFFF", 12);
$mainLayer->addLayerOnTop($textSumLayer, 510, 513, "LT");

// Добавление текстового слоя с надписью 'руб.'
$textRubLayer = PHPImageWorkshop\ImageWorkshop::initTextLayer('руб.', $imagePath.'/OpenSans-Bold.ttf', 15, "FFFFFF", 12);
$mainLayer->addLayerOnTop($textRubLayer, 585, 505, "LT");

// Сохранение готового изображения (если требуется)
$mainLayer->save($imagePath, 'collage.jpg', true, null, $quality);

// Если требуется отдать созданное изображение в браузер
$image = $mainLayer->getResult();
header('Content-type: image/jpeg');
header('Content-Disposition: filename="collage.jpg"');
imagejpeg($image, null, $quality);
exit;
                    

А вот и результат!

Готовый коллаж

В этой статье показаны только основные возможности PHP Image Workshop. Для ознакомления с полным списком необходимо заглянуть на страницу документации на сайте разработчика.