1 июня 2008 в 02:30

Фотошопим на PHP

Уменьшаем изображение разными библиотеками и сравниваем результат

Для многих задач автоматической обработки фотографий не подходит качество и функционал библиотеки GD. Поскольку возможности обратиться к Photoshop из PHP или Perl пока не существует, решаем проблему с помощью ImageMagick.

Речь пойдет о PHP инрефейсе к ImageMagick MagickWand, который в репозитарии Fedora называется php-magickwand. Хочу обратить Ваше внимание, что MagickWand API отличается от классического ImageMagick тем что позволяет работать как с элементами растровой графики, так и с элементами векторной графики.

Для php есть еще одна реализация интерфейса к ImageMagick, которая называется IMagick, но функционал этой библиотеки, на мой взгляд, уступет MagickWand.


В первой статье рассмотрим на примерах несколько типичных задач по обработке изображений и сравним результаты с php-gd.




Уменьшаем картинку



Уменьшаем изображение вот таким простым кодом
  $magick_wand=NewMagickWand();
  MagickReadImage($magick_wand,'linux_users.jpg');
  $mgck_local=MagickTransformImage($magick_wand, NULL,'x100');
  MagickStripImage($mgck_local);
  MagickEchoImageBlob($mgck_local);


'x100' означает по вертикали 100, по горизонтали сколько получиться,
второй параметр отвечает за функции обрезки изображения мы их в нашем примере не используем. MagickStripImage убирает комментарии, иногда заметно уменьшает размер маленьких изображений.

Опытный web-дизайнер знает, что при сильном уменьшении изображения для Web,
чтоб картинка выглядела более презентабельно, ей немного добавляют резкости. Параметры наведение резкости зависит от размера картинки, ну и собственно от художественного вкуса дизайнера. Наводим резкость средствами MagickWand:

  $magick_wand=NewMagickWand();
  MagickReadImage($magick_wand,'linux_users.jpg');
  $mgck_local=MagickTransformImage($magick_wand, NULL,'x100');
  MagickSharpenImage($mgck_local,1,4);
  MagickStripImage($mgck_local);
  MagickEchoImageBlob($mgck_local);



Теперь сравним результаты, проделаем операцию уменьшения с помощью GD, в режиме по умолчанию и с 100% сохранением качества.

Режим обработки Изображение
GD режим «по умолчанию» (2 351 b)
Очень маленький размер но потеря качества уже заметна
GD 100% качество (7 847 b)
Качество хорошее, GD все делает отлично!
MagickWand «по умолчанию» (9 695 b)
Качество хорошее, но размер немного больше!
MagickWand + наведение резкости (14 508 b)
Здесь картинка без сомнения выглядит лучше предложенных вариантов!

Олег Черний @apelsyn
карма
143,1
рейтинг 0,0
Похожие публикации
Самое читаемое

Комментарии (31)

  • 0
    Спасибо!
    Пошёл читать и тестить.
  • НЛО прилетело и опубликовало эту надпись здесь
  • –1
    "Сдесь" и "матерриалы" портят оформление отличной идеи. За идею - двойное спасибо ;)
    • 0
      и еще "несколько 3-4 года", а также "результатиы, продалаем", "заметную", "чтоб", "собствнно".
      Надо проверять хотя бы вордом, или гуглом, "потому что он исправляет слова, в которых больше одной ошибки" ©bash.
      • +1
        Спасибо за замечание, действительно забыл проверить на грамотность. Уже исправил.
        • 0
          да ничего ;) с кем не бывает.
  • +1
    Спасибо, интересно, мы тоже выбрали ImageMagick для своего проекта.
    На мой взгляд, у вас шарпинг чрезмерен
    Вот www.xl-tour.ru/imagick/cmd.php мой программист написал скриптик, позволяющий на примере одной фотки поиграться с шарпингом и качеством файла при обработке через ImageMagick.
    Пока мы для себя выбрали следующие параметры:
    convert result.jpg -resize 600x -unsharp 0.2x0+300+0 –compress JPEG -quality 80 result.jpg

    Сравнивали с фотошопом, он при тех же параметрах шарпинга, и качестве сохранения 51% делает фотографии чуть меньше и чуть лучше. К сожалению, перегнать фотошоп нам пока не удалось.
    • 0
      Adobe всегда славился своими конвертерами, тут уж ничего не поделать.
    • 0
      Согласен, но так нагляднее. В нашем деле не бывает правильной цифры :), шарпинг зависит и от размера фотографии чем меньше превьюшка - тем аккуратнее нужно наводить резкость.
  • +2
    Пост — в закладки, спасибо — в карму;-)
    • –1
      Ананлогично :)
  • 0
    Огромное спасибо! Проектируем фотохостинг и буквально позовчера встала именна эта проблема, проблема в качестве и четкости превьюшек.
    Прямо по щучьему велению. :-)
    • +2
      о! обращаюсь к вам как к доблесным разработчикам в будущем великого фотохостинга:
      1. не убирайте картинки, на которые идет большая нагрузка!
      2. прикрутите статистику просмотров и т.п.
      3. и апи, да
  • 0
    Вот сколько ни вглядывался, разницы между изображениями, кроме как с первым, не заметил...
    • +1
      Возможно, я выбрал не совсем удачную фотку, которая для меня ассоциируется с GNU/Linux-сообществом :). Тогда я попробую продемонстрировать разницу на примере фото Ричарда Столлмана:
      Фото Ричарда Мэттью Столлмана, до шарпинга MagickWandФото Ричарда Мэттью Столлмана, после шарпинга MagickWand
      Разницу можно увидеть в мелких деталях: борода, глаза, рот. Я специально для MagickWand поставил 100% качество, чтоб на разницу не влияла компрессия. Параметры Шарпинга те же: MagickSharpenImage($mgck_local,1,4)
  • 0
    Здорово, что хоть кто-то решился написать о данной библиотеке. Буквально только позавчера тут говорили о том, что PHP+GD1/2 стандартный вариант, но PHP+IM все же мощнее. Единственно что меня в MagickWand смещает это не всегда понятная документация (местами вообще было не ясно, что же имел в виду автор документации) и практически полное отсутсвие примеров. Ну и процедурный стиль конечно тоже немного напрягает.

    Имхо, IM в рунете освещен не очень хорошо.

    Автору спасибо. Мог бы, поставил бы плюс.
    • 0
      стиль процедурный, но подход объектно-ориентированный. Практически все методы используют id-шник созданного wand'а в качестве первого параметра. Это типично для нскоро портированных в ОО язык чисто-сишных API. Такая же ситуация в curl'е. Это нормально. кроме того несложно написать обёртку, выглядящю как нормальный OO API.

      Кстати про работу с текстом и вектором в "классическом ImageMagick" (видимо имеется ввиду commnd-line интерфейс) автор обманывает: из коммандной строки convert умеет абсолютно всё, что умеет библиотека MagickWand.

      собственно, я пользуюсь комманд-лайном - это позволяет одновременно и ворочать большие картинки и не выделять php для этого кучу памяти, которую если разрешить он потенциально может отъесть в других местах, не связанных с графикой (чего я не хочу [-: ).
  • 0
    Спасибо. Как-то раз заказчик как раз жаловался на качество превьюшек. Я не знал, что ему ответить и ссылался на ограничения технических средств. :) Теперь все встало на свои места.
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      о сенкс, про шарпинг актуально.
    • 0
      IM при ресайзе чуть быстрее на больших картинках (более 6000x6000 px), на маленьких (типа обоев на рабочий стол) разницы не заметил.

      Вообще сравнивать phpThumbs и IM не совсем корректно, ибо thumbs использует IM если он установлен, и только в крайнем случае обращается к GD. Я, кстати, вообще не уверен, что он умеет шарпинг на чистом GD - не пробовал. (-:
  • 0
    кстати, очень жаль, что IM активно не развивается вот уже много лет. Активно - я под этим понимаю написание новых фильтров и улучшение удобства работы с утилитой convert (там очень неудобна для понимания система "гравитации" при нарезке изображений). Например очень не хватает фильтров, которые "вытягивают" недодержанные участки изображения или создают блики в ярких местах, итп.
  • 0
    А мы для Unsharp используем Unsharp Mask for PHP - которая замечательно работает с GD.

    http://vikjavev.no/computing/ump.php
    • 0
      Не знал об этой библиотеке, спасибо что написали.

      Это не функция движка GD, она написана на самом php и как вы, сами понимаете, она очень заметно проигрывает в скорости.

      Я 100 раз сделал шарпинг с помощью Unsharp Mask for PHP вышеупомянутому фото - это заняло 17 секунд, аналогичная операция на MagickWand заняла 0,6 секунды (Почти в 30 раз медленее!). А если шарпить прийдется 640x480 тогда потеря производительности будет гораздо ощутимее.

      Качество шарпинга с натяжкой можно стравнивать с MagickWand.
    • 0
      С качеством я поспешил делать выводы. Когда установил идентичные параметры шарпинга, "на-глаз", разницу с MagickWand не увидел.

      Проблема останется только в производительности, упомянутой Вами, функции.
  • 0
    Как по мне, то документация не ахти, да и либа не самая адекватная (производительность на высоте но стабильность ...).
    Например под Freebsd есть проект который использует ф-цию MagickPaintOpaqueImage, перенесли проект под Linux(ubuntu), перестало работать, оказалось не знает magickwand такую ф-цию MagickPaintOpaqueImage, далее пришло обновление и для фри, и те же пироги, все лягло, просто исчезла функция :(
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Обновите ImageMagick или поставте MagickWand 1.0.6.

      В новом ImageMagick, конфигуратор называется MagickWand-config а не Wand-config
  • 0
    Пожалуйста, подскажите, чем лучше нарезать на кусочки фиксированного размера (256x256) очень большую картинку (tiff) с разрешением 17002x19002 *750мб) точек (и еще одну картинку 27000x20000 н 1.56гб)
    convert из ImageMagick у меня на первой картинке уходит думать в вечность,
    а на второй просто вылетает по недостатку памяти.
    Фотошоп открывает, но там я не знаю, как это автоматизировать.
    • 0
      Я не пользуюсь convert (работа из консоли очень ограничивает возможности этой библиотеки, кроме того вы не можете определить как каком этапе ImageMagick "уходит в космос").

      Мои пользователи не заливают мне файлы такого разрешения :). Поєтому дам рекомендации исходя из того как решал бы проблему я.

      Поделим все на этапы:

      1. Увеличьте в php максимальный предел загребаемого ОЗУ, примерно так
      ini_set('memory_limit', '2048M');
      set_time_limit(0);


      2. Загрузите изображение в память
      $magick_wand=NewMagickWand();
      MagickReadImage($magick_wand,'my_big.tif');


      3. Если эти этапы прошли, напишите прогу которая будет вырезать куски, этого я за Вас делать не буду.

      Главное в во всем этом то, что вы можете видеть на каком шаге затык! Ну в крайнем случае RAM в комп добавте :). У меня на серваке 8G стоит, думаю он бы проглотил имидж в полтора гига.
      • 0
        Понятно, будем пробовать,
        хотя на моем сервере только 2мб памяти :(
        Просто, я надеялся, что есть программное решение, позволяющее резать картинку на кусочки без создания ее полного образа в памяти.
        Одна из таких программ у меня есть, но она вообще не имеет настроек и на выходе выдает jpeg с фиксированными параметрами компресии, но зато "стрижет" такие картинище на картинки очень быстро (за 1-3 минуты) и памяти почти не требует.
        Результат нарезки:
        www.kartaspb.ru
        www.oblmap.spb.ru
        Хотел переделать формат на gif/png с индексными палитрами и сжатием без потерь (думал, что будут получаться файлы меньшего размера и лучшего качества), но простого способа пока не нашел.

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