Человек-без-прошлого (sontar) wrote in ru_php,
Человек-без-прошлого
sontar
ru_php

Categories:
  • Mood:
  • Music:

Обработка изображений с помощью ImageMagick

Краткий курс для тех, кто никогда не работал с сабжем.

В программе:
0. Введение;
1. Масштабирование изображений, создание миниатюр с помощью ImageMagick;
10. Наложение водяных знаков (надписи) с помощью ImageMagick;
11. Скругление углов у изображений с помощью ImageMagick.


0. Введение
ImageMagick - это пакет программ, предназначенных для операций с изображениями. Офсайт: http://www.imagemagick.org/ - там всё, и документация, и примеры, и скомпилированные версии программ под unix и win32.
К достоинствам ImageMagick можно отнести скорость работы, возможность масштабирования анимированных gif, отсутствие падения основного скрипта при неудачной операции над изображениями (хотя у меня неудачных операций над изображениями ещё ни разу не случалось).
Самого исполняемого файла imagemagic в пакете нет, а есть другие: animate, compare, composite, convert и другие (в win-версии они называются соответственно animate.exe, compare.exe и т.д.). Наиболее часто используемый файл - convert[.exe], он-то нам и нужен. Все параметры convert можно прочитать здесь.

Как запустить convert[.exe] из php:
$command = "convert [параметры]";
exec($command);

В дальнейшем, когда я буду описывать команду, я буду иметь ввиду только часть, выделенную жёлтым. Например
> convert image.jpg image.png
при переносе в php-скрипт будет означать
$command = "convert image.jpg image.png";
exec($command);

Команда без пути и расширения ".exe" работает и в unix и в win32 - версиях.

Как установить ImageMagick:
В GNU/linux: apt-get install imagemagick (debian/ubuntu) либо yum install imagemagick (red hat/centos) либо из портов (freebsd).

В windows установка простая: распаковываете архив imagemagick в любую папку. ЕМНИП, там есть инсталлятор, но его роль формальна, он служит только в качестве распаковщика.
Чтобы convert[.exe] запустился, путь к нему должен быть указан в параметре PATH. Откройте phpinfo, найдите раздел Apache Environment и в нём переменную PATH. Если пути к вашей папке с imagemagick там ещё нет, то: можете внести пусть в переменную окружения PATH системы целиком, либо если у вас denwer - найдите файл apache.pl, строку StartManager::action, ниже неё PATH => и исправьте примерно следующим образом:
  PATH => [
   '\usr\local\ImageMagick',
   @addPath,
  ],

Чтобы проверить, работает ли - создайте тестовый php-скрипт, в котором указана команда
> convert image.jpg image.png
Положите рядом с ним файл image.jpg и запустите скрипт. Если image.png появился - значит всё ок. Проще некуда.

Теперь внимание. В документации приводятся примеры с использованием одинарных кавычек в параметрах:
> convert -size 10x10 xc:skyblue -fill black -draw 'point 3,2' -scale 100x60 draw_point.gif
Так вот, используйте только двойные, т.е.
> convert -size 10x10 xc:skyblue -fill black -draw "point 3,2" -scale 100x60 draw_point.gif
При переносе в php нужно добавить бэкслеши:
$command = "convert -size 10x10 xc:skyblue -fill black -draw \"point 3,2\" -scale 100x60 draw_point.gif";
Вариант с одинарными кавычками имеет шанс не заработать (как у меня в windows). Двойные кавычки же удобно использовать для подстановки параметров и названий файлов.

Ещё один интересный момент - в рунете внятной документации и примеров по imagemagick я почти не встречал, даже скругление углов некий автор предлагал делать через... в общем не будем об этом печальном случае. Положительная же новость - что масса примеров находится на офсайте в разделе Usage, рекомендую сразу заглядывать туда.

Imagick и Magickwand
Это специальные библиотеки, служащие оболочкой для ImageMagick утилит. Всякая операция с файлами через эти интерфейсы (классы) вызывает convert[.exe] или другой файл из пакета. По сути это есть ImageMagick, только в более медленном, более ресурсоёмком и более скудном возможностями варианте.
Об их наличии можно узнать через phpinfo() - должны быть показаны одноимённые секции.
Поскольку эти библиотеки являются аналогами, и ни одна из них не является стандартом - их не устанавливают обе сразу, а значит использующему одну из этих библиотек скрипту на новом хостинге может быть недоступен функционал для работы с изображениями.
Это аргументы в пользу того, чтобы работать с ImageMagick утилитами напрямую из командной строки.

Итак, приступим:

1. Масштабирование изображений, создание миниатюр.
Дано: изображение заранее неизвестных размеров, товар лицом, так сказать. Купи слона, чувак. (1.jpg):



У этого размеры 650х393px, и это хорошо для наших примеров из-за отсутствия классических пропорций.

Нам нужно получить из него: а) уменьшенное изображение для вёб-страницы размером ДО 400х300 px, с автоматической ориентацией. Т.е. для вертикально ориентированных картинок эти размеры будут 300х400 соответственно. б) миниатюру размером 132х132, при этом выступающие края должны быть обрезаны.
Типичные задачи для каталога товаров - миниатюра не должна рвать вёрстку, а на большом изображении должна быть видна вся область.

а) Само изменение размеров с сохранением пропорций делается простой командой
> convert 1.jpg -resize "400x300" 2.jpg
Результат (2.jpg):


Его размеры 400х242, были автоматически вычислены. Но мы могли бы вычислить их заранее и подставить:
> convert 1.jpg -resize "400x242" 2.jpg
Дало бы то же самое.

Что делать, если картинка имеет вертикальную ориентацию? Предположим, мы рекламируем лекарства (1v.jpg), 347x480px:



Наверняка есть какая-то команда (какая?) для автоопределения размеров, но я её не знаю и использую вот такую функцию http://php.pastebin.com/f769c8683. Ну да, я её сам написал, берите, пользуйтесь. Эта волшебная функция говорит нам, что конечные размеры в последнем случае будут 289х400px. Так и запишем:
> convert 1v.jpg -resize "289x400" 2v.jpg
Результат:


б) Создадим миниатюру. Конечные размеры нам известны, ничего вычислять не надо. Сперва изображение уменьшается, затем кадрируется. 
Уменьшаем следующим образом:
> convert 1.jpg -resize "132x132^" 3.tmp.jpg
У нас получатся следующие картинки (затемнены области, которые нужно будет отрезать при кадрировании)
 

Символ ^ означает выполнить масштабирование так, чтобы вся область 132х132 оказалась заполненной, не было пустых мест.

Теперь выполняем кадрирование
> convert 3.tmp.jpg -gravity center -crop 132x132+0+0 +repage 3.jpg
-gravity center означает выполнить следующую операцию, отталкиваясь от центра изображения.
-crop 132x132+0+0 означает выполнить кадрирование с заданными размерами и смещением
+repage - пересчитать конечные размеры изображения

 

Команды можно объединить
> convert 1.jpg -resize "132x132^" -gravity center -crop 132x132+0+0 +repage 3.jpg

10. Наложение водяных знаков-надписей
Возьмём изображение 2.jpg и добавим к ней текст "community.livejournal.com/ru_php":
> convert 2.jpg -font Tahoma -pointsize 16 -draw "gravity SouthEast fill gray text 0,1 'community.livejournal.com/ru_php' fill white text 1,0 'community.livejournal.com/ru_php' " 4.jpg



-font Tahoma - выбор шрифта
- pointsize 16 - высота надписи
gravity SouthEast - "притяжение" к углу юго-восток (нижний правый)
fill gray / fill white - цвет заливки. можно указывать в формате #RRGGBB
text 0,1 'текст' - написать текст с заданным смещением

Также можно накладывать водяные знаки-картинки или рисовать специальными командами, об этом читайте в Usage.

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


А можно сделать jpeg-ом, тогда вес картинки небольших размеров будет в четыре раза меньше:


Если мы кладём картинку на белый фон - мы делаем белые уголки, на синий - синие, если цвет фона заранее неизвестен - делаем png с прозрачными углами.

Как добиться скруглённых уголков? В три шага:

Первый шаг - создание mvg-файла
> convert 3.jpg -border 0 -format "fill #ffffff rectangle 0,0 %[fx:w],%[fx:h]" info: > tmp.mvg
Это специальный промежуточный формат ImageMagick. В файле tmp.mvg будет храниться что-то вроде
fill #ffffff rectangle 132x132
Он нужен нам для создания залитого белым png-файла
> convert 3.jpg -matte -channel RGBA -threshold -1 -draw "@tmp.mvg" PNG:underlay.png
получим файл underlay.png размером 132х132 совсем #ffffff, так что показывать не буду. Underlay - потому что мы его подложим под картинку, чтоб прозрачные уголки сделать белыми - это позволит нам сохранить конечную картинку в jpg а не png, тем самым уменьшив вес. Хотя на имя файла похрен, сами понимаете.
Последний шаг:
> convert underlay.png ( 3.jpg ( +clone -threshold -1 -draw "fill black polygon 0,0 0,15 15,0 fill white circle 15,15 15,0" ( +clone -flip ) -compose Multiply -composite ( +clone -flop ) -compose Multiply -composite -blur 1x1 ) +matte -compose CopyOpacity -composite ) -matte -compose over -composite 5.jpg

Будут созданы файлы tmp.mvg и underlay.png, по окончании всех операций их нужно удалить.

То, что здесь написано - для случая с непрозрачным jpg-файлом. Если нам нужен полупрозрачный png - выполняем всего одну команду:
> convert 3.jpg ( +clone -threshold -1 -draw "fill black polygon 0,0 0,15 15,0 fill white circle 15,15 15,0" ( +clone -flip ) -compose Multiply -composite ( +clone -flop ) -compose Multiply -composite -blur 1x1 ) +matte -compose CopyOpacity -composite 5.png

Радиус скругления - 15, можно изменить. Цвет выделен жирным. Между скобками и остальными командами должны быть пробелы, иначе команды не распознаются.

 

Все примеры рабочие. Покупайте наших слонов.


Бонус - функция, служащая оболочкой для convert, т.е. не требующая операций с командной строкой http://php.pastebin.com/f3754e7fc . Работает в совокупности с указанной выше функцией. Она может выполнять масштабирование с учётом автоориентации и кадрирование изображений.
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 48 comments