Классы для работы с изображениями

Den Kulikoff [30.12.2011]

При всей своей замечательности Parser имеет очень ограниченный набор функций для работы с изображениями. Тем не менее при создании сайтов с использованием данного языка периодически возникает необходимость изменить размер изображения, повернуть его или сохранить в другом формате.

Что ж, как обычно, если Parser чего-то не умеет, то надо вызвать внешний скрипт, который может сделать необходимое и воспользоваться результатом его работы. И тут нам на помощь приходит замечательная утилита nconvert. (За наводку спасибо Eugene Spearance). Утилита может много чего. Поэтому для маньяков возможности по работе с изображениями теперь ограничены только их маньячной фантазией :). Поскольку я маньяком не являюсь, то в описываемом классе реализованы основные возможности для работы с картинками.

Немного позже Misha v.3 предложил сделать класс более универсальным и совместить его еще и с ImageMagick'ом. Для этого в исходном Img.p были оставлены только методы, определяющие интерфейс работы с классом. Все же, что занимается вызовом внешних скриптов и некоторые специфические вещи были вынесены в соответствующие классы NConvert.p и ImageMagick.p, которые являются наследниками класса Img.

Для чего все это нужно? А что бы не было мучительно больно, когда при переезде на другой хостинг вы обнаруживаете, что там нету ImageMagick или для тамошней ОС нет нужной версии nconvert'a. В этом случае, при использовании описываемого набора классов, вам нужно лишь подключить NConvert.p вместо используемого ImageMagick.p (или наоборот) и все. Больше в коде ничего менять не нужно. И не надо думать, что переезжать не придется. Как только вы так подумаете, то придется, обязательно! :)

Итак, что может класс и как с ним работать

Для начала надо определиться какой именно внешней программой вы будете пользоваться

Если выбран NConvert

Надо скачать c сайта бинарик, скомпилированный для вашей ОС. Положить его на сервер (желательно вне веб-пространства) и назначить файлу права на запуск.

Затем, скачать архив и поместить Img.p и NConvert.p из него туда, где у вас живут аналогичные файлы.

 

Если выбран ImageMagick

Для начала узнайте не установлен ли у вашего хостера пакет ImageMagick. Если да, что узнайте где лежит convert из него. А если нет, то идем на сайт, скачиваем дистрибутив для своей ОС и устанавливаем по описанию (желающие могут собрать из исходников).

Затем, скачать архив и поместить Img.p и ImageMagick.p из него туда, где у вас живут аналогичные файлы.

Создаем объект

^use[NConvert.p]
$oImg[^NConvert::create[
#	Путь, где лежит nconvert
	$.sScriptPath[/../data/bin]
#	Имя самого файла nconvert
	$.sScriptName[nconvert]
]]

 
^use[ImageMagick.p]
$oImg[^ImageMagick::create[
#	Путь, где находится convert из пакета ImageMagick
	$.sScriptPath[/../data/bin/ImageMagick]
#	Имя самого файла
	$.sScriptName[convert]
#       Имя файла composite для @watermark[] (если он используется)
       $.hScriptName[
               $.watermark[composite]
       ]
]]

Все, на этом различия закончены. Теперь мы можем пользоваться методами объекта $oImg, которые имеют единый интерфейс, независимо от того, какой внешней программой мы пользуемся.

Примечания:

Получение информации об изображении

^oImg.info[$sFileSrc]
Возвращает следующий хэш
	$.sFormat	- формат
	$.iWidth	- ширина (px)
	$.iHeight	- высота (px)
	$.sCompression	- сжатие
	$.iColors	- кол-во цветов
	$.iXdpi		- разрешение по горизонтали (dpi)
	$.iYdpi		- разрешение по вертикали (dpi)
	$.sOrientation
	
Так же, при использовании ImageMagick может присутствовать поле:
	$.sQuality	

Конвертирование изображения в необходимый формат

^oImg.convert[$sFileSrc;$sFileDest;$sFormat;$hParams]

Здесь
$sFormat - выходной формат
$hParams - хэш со следующими полями
	$.bRemoveMeta	- флаг удаления метаданных
	$.iQuality	- качество для jpg и png.
	$.iColors	- кол-во цветов (256, 216, 128, 64, 32, 16 или 8)

Изменение размера изображения

^oImg.resize[$sFileSrc;$sFileDest;$sWidth;$sHeight;$hParams]

Здесь
$sWidth и $sHeight и высота получаемого изображения соответственно
$hParams - хэш со следующими полями
	$.bKeepRatio	- флаг сохранения пропорций (по умолчанию 0) 
	$.sResizeType	- тип изменения размера 
		incr	: только увеличение
		decr	: только уменьшение
	$.bRemoveMeta	- флаг удаления метаданных
	$.sFormat	- выходной формат
	$.iQuality	- качество для jpg и png
	$.iColors	- кол-во цветов (256, 216, 128, 64, 32, 16 или 8)
	$.sResampleType	- Алгоритм при изменении размера
		lz,lanczos	: Lanczos (по умолчанию)
		g,gaussian	: Gaussian
		m,mitchell	: Mitchell

#	только для NConvert
		q, quick	: Quick resize
		l, linear	: Bi-linear (linear)
		h, hermite	: Hermite
		b, bell		: Bell
		bs, bspline	: Bspline

Вырезание прямоугольной области (crop)

^oImg.crop[$sFileSrc;$sFileDest;$iX;$iY;$iCropWidth;$iCropHeight;$hParams]

Здесь
$iX		- x-координата левого верхнего угла
$iY		- y-координата левого верхнего угла
$iCropWidth	- ширина области
$iCropHeight	- высота области
$hParams - хэш со следующими полями
	$.sFormat	- выходной формат
	$.bRemoveMeta	- флаг удаления метаданных
	$.iQuality	- качество для jpg и png
	$.iColors	- кол-во цветов (256, 216, 128, 64, 32, 16 или 8)

Наложение "водяных знаков"

^oImg.watermark[$sFileSrc;$sFileDest;$sWMFile;$hParams]

Здесь
$sWMFile - накладываемое изображение (лучше всего использовать полупрозрачный png)
$hParams - хэш со следующими полями
	$.iX		- x-координата левого верхнего угла накладываемого изображения
	$.iY		- y-координата левого верхнего угла накладываемого изображения
	$.sPosition	- позиция накладываемого изображения
		top-left, left-top		: top-left
		top-center, center-top		: top-center
		top-right, right-top		: top-right
		center-left, left-center	: center-left
		center				: center
		center-right, right-center	: center-right
		bottom-left, left-bottom	: bottom-left
		bottom-center, center-bottom	: bottom-center
		bottom-right, right-bottom	: bottom-right
	$.sFormat	- выходной формат (кроме gif)
	$.bRemoveMeta	- флаг удаления метаданных
	$.iQuality	- качество для jpg и png
Указывается либо позиция, либо координаты

Примечание:

При использовании ImageMagick надо не забыть при создании объекта указать имя скрипты, который будет отвечать за данное преобразование

^use[ImageMagick.p]
$oImg[^ImageMagick::create[
#	Путь, где находится convert из пакета ImageMagick
	$.sScriptPath[/../data/bin/ImageMagick]
#	Имя самого файла
	$.sScriptName[convert]
#       Имя файла composite для @watermark[] (если он используется)
       $.hScriptName[
               $.watermark[composite]
       ]
]]

Поворот изображения

^oImg.rotate[$sFileSrc;$sFileDest;$iAngle;$hParams]

Здесь
$iAngle - угол в градусах
$hParams - хэш со следующими полями
	$.sBGColor	- цвет фона (формат "R,G,B")
	$.sFormat	- выходной формат
	$.bRemoveMeta	- флаг удаления метаданных
	$.iQuality	- качество для jpg и png
	$.iColors	- кол-во цветов (256, 216, 128, 64, 32, 16 или 8)


Следующий метод работает только при использовании NConvert.
^rotateJPEG[] не реализован в классе ImageMagick, т.к. в одноименной библиотеке отсутствует подобный функционал.

Поворот JPEG без потери качества

^oImg.rotateJPG[$sFileSrc;$iAngle]

Здесь $iAngle - угол поворота в градусах (+/-90, 180, +/-270)
В результате исходный файл заменяется

За критику и дельные советы большое спасибо Misha v.3

Если кто-то пользуется другими утилитами для работы с изображениями, то welcome :)

Вот собственно и все.

Скачать: Img.zip (18.10.2013, 5.85 КБ)
Архив с классами Img, ImageMagick, NConvert