Работа с изображениями средствами phpThumbOf

Original author: Aaron Belafonte
  • Translation
phpThumbOf — это аддон для MODx, основанный на популярном скрипте phpThumb. Он позволяет модифицировать изображения средствами различных графических библиотек «на лету».

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

Причиной написания поста послужил тот факт, что официальная документация по phpThumbOf просто ужасна. Прочитав ман, я подумал, что единственной функцией, которую можно использовать для модификации изображения при его выводе является зум-кроп (zoom-crop), ибо больше там ничего не сказано. Но позже, попробовав использовать некоторые другие опции phpThumb я выяснил, что они прекрасно работают!

 

Анатомия phpThumbOf — фильтр вывода


Фильтр Вывода MODx-а позволяет прогнать значение элемента через любой набор фильтров непосредственно перед его выводом на страницу. Синтаксис выглядит следующим образом:
[[element:modifier=`value`]]

Первым и наиболее правильным способом использования phpThumbOf является именно Фильтра Вывода, который добавляется к TV-параметру типа «изображение».

Просто для полноты рассказа, я покажу, как добавить такой tv-параметр к шаблону.

Для начала, создайте новый tv-параметр и назовите его как сочтёте нужным. Мой вариант:


Далее, в закладке «Тип ввода» выберите «Изображение»:


Все, что нам осталось сделать, это указать способ вывода tv-параметра — ставим SRC.

Для экспериментов выберем какую-нибудь интересную картинку. Я нашёл себе такую:


Теперь, когда мы указали в каком-нибудь ресурсе выбранную нами куртинку в качестве значения созданного нами дополнительного параметра, его можно вывести в контенте ресурса с помощью конструкции:
<img src="[[*tvImage]]" />

Как я упоминал в начале статьи, выходной фильтр изменяет элемент до того, как он будет отрисован на странице. Передадим значение нашего tv-параметра выходному фильтру phpThumbOf:
[[*tvImage:phpthumbof=`w=120&h=120`]]

Ремарка: если мы выводим tv-параметр в шаблоне или чанке, то знак звездочка "*" нужно заменить на плюс "+": [[+tvImage:phpthumbof=`w=120&h=120`]]

В результате, мы получим новое сгенерированное изображение, основанное на той картинке, что мы выбрали для ресурса, но масштабированное до размеров 120х120 пикселей. Но как Вы могли заметить, у изображения появились белые поля, возникшие из-за нарушения пропорций исходного изображения.


Избежать этого можно очень просто, достаточно не указывать ширину или высоту. Давайте оставим только фиксированную ширину:
[[+tvImage:phpthumbof=`w=120`]]

Теперь результирующее изображение отмасштабировано только по заданной ширине, высота будет пропорциональной исходному соотношению сторон.


Как Вы можете видеть, возможности ресайза изображений безгранично гибки. Вот ещё один пример с шириной 270 пикселей. Кроме того, вы можете получать на выходе изображения больше оригинального, но это порочная практика ;).
[[*tvImage:phpthumbof=`w=270`]]



 

Обрезка изображения с точными размерами


Если мы хотим получить изображение с размерами именно 120 на 120 пикселей, мы можем его обрезать. Для этого, необходимо добавить опцию кропа (zoom-crop) &zc=1.
[[*tvImage:phpthumbof=`w=120&h=120&zc=1`]]

Теперь мы имеем обрезанную версию нашего изображения с точными размерами и без белых полей.


 

Фильтры PhpThumb — веселье только начинается


Теперь, когда вы знаете, как управлять размером изображения, я покажу вам реальную силу phpThumb — фильтры. Я просто приведу несколько примеров фильтров, доступных в phpThumb. Обратите внимание, что все новые фильтры я добавляю в конец предыдущих примеров. При этом, их позиция имеет значение! Фильтры применяются слева направо.

 

Blur (размытие)


[[*tvImage:phpthumbof=`w=120&h=120&zc=1&fltr[]=blur|10`]]



 

Grayscale (преобразование палитры в градации серого)


[[*tvImage:phpthumbof=`w=120&h=120&zc=1&fltr[]=gray`]]



 

Скругление углов


[[*tvImage:phpthumbof=`w=120&h=120&zc=1&fltr[]=ric|20|20`]]



Обратите внимание, что у изображения появились белые углы в тех местах, где изображение «скруглилось». Мы можем побороть эту проблему, преобразовав результирующее изображение в PNG-формат.
[[*tvImage:phpthumbof=`w=120&h=120&zc=1&f=png&fltr[]=ric|20|20`]]



 

Рамка


Периодически возникает необходимость добавить к изображению рамку. Конечно, это можно сделать средствами CSS. Но иногда возникают моменты, когда CSS бесполезен. Я хочу показать Вам один из таких примеров.
[[*tvImage:phpthumbof=`w=120&h=120&zc=1&f=png&fltr[]=bord|5|0|0|FFFFFF&fltr[]=rot|-15|E4F6FE`]]



 

Вращение изображения


Вращение требует небольшого пояснения. Вы должны указать цвет фона для неграфических области в углах. В этом примере мы используем #006699, вращение -45°.
[[*tvImage:phpthumbof=`w=120&h=120&zc=1&fltr[]=rot|-45|006699`]]



Если Вы хотите уменьшить количество JPG=артефактов, вы можете увеличить качество изображения (1-100):
[[*tvImage:phpthumbof=`w=120&h=120&zc=1&fltr[]=rot|-45|006699&q=100`]]



Если Вы хотите получить прозрачный фон, просто измените вывод в PNG, как мы делали это раньше:
[[*tvImage:phpthumbof=`w=120&h=120&zc=1&fltr[]=rot|-45|&f=png`]]



 

Color Overlay (наложение цвета)


Данный фильтр позволяет накладывать любые шестнадцатеричные цвета на изображение. Первое значение — процент, второе — цвет в шестнадцатеричном формате.
[[*tvImage:phpthumbof=`w=120&h=120&zc=1&fltr[]=clr|35|990033`]]



Если Вы хотите получить двухцветное изображение, необходимо сначала наложить фильтр grayscale для обесцвечивания картинки.
[[*tvImage:phpthumbof=`w=120&h=120&zc=1&fltr[]=gray&fltr[]=clr|35|990033`]]



 

Простой текстовый водяной знак



С помощью phpThumb Вы можете накладывать на изображение текстовые и графические водяные знаки. В случае с текстовыми вотермарками Вы можете указать размер, положение, прозрачность и TTF-шрифт.

Вообще, доступных очень много. Рекомендую ознакомиться с документацией.

Вот простой водяной знак на основе стандартного шрифта сервера:
[[*tvImage:phpthumbof=`w=120&h=120&zc=1&fltr[]=gray&fltr[]=wmt|Belafonte Code|3|T|FFFFFF||100|20|0||0|`]]



 

Финиш


Вот, наверно, и все о чем я хотел рассказать. С бОльшим количеством примеров использования phpThumb вы можете ознакомиться на официальной странице проекта.

P.S. Хотел опубликовать в блог «MODx CMS», но как обычно бывает на хабре, не хватило кармы.
P.S.S. Перенес в «MODx CMS»
Share post

Comments 27

    0
    Спасибо за наводку на хорошую библиотеку для работы с миниатюрами. А то уже забадался велосипеды изобретать.
      +5
      Пхп-Тамбов.
        0
        Спасибо, вовремя.
          0
          Что-то не поняла я…
          Фильтры вывода??? Т.е. изображение модифицируется не при загрузке, а при отображении? И если у меня в галерее 100 превьюх на одной странице — то при каждом просмотре страницы эти превьюхи генерятся на PHP? Хм…
            0
            Может быть он их как то все же кеширует? Не думаю что все настолько плохо, а то 100 превьюх для файлов по 10 метров будет накладненько каждый раз генерировать.
              0
              они кешируются
                0
                нет создает и сохраняет в папке cache — если следующий раз с такими же параметрами вызывается изображение, то обращается к уже существующему.
                  0
                  А если исходная картинка с этого времени изменилась?
                    0
                    Вообще — перегенерирует, но тут уже броузер свой кэш включает.

                    Поэтому, я добавляю ?timestampобновления, чтобы броузер выводил новые картинки всегда.
                      0
                      Вообще это не правильно. На сайтам с большим количеством картинок будет лишняя (довольно большая) и совсем не нужная нагрузка + замедление скорости открытия сайта.
                      Надо чтобы картинки отдавались напрямую nginx-ом, без задействования php. Но тогда они должны приводиться к требуемому виду во время добавления на сайт.
                        0
                        Так они ж и отдаются.

                        Первый раз php генерирует уменьшенную картинку и кладет ее в папку кэша. Там эта картина и лежит. Лично у меня лежат скриншоты сайтов — они обновляются периодически. Имена картинок и кэшированных копий при этом не меняются.

                        Nginx отдает картинку. Броузер видит, что адрес картинки прежний — и выводит свою сохраненную копию (старую картинку). Поэтому я добавляю к адресу timestamp последнего обновления ссылки (у меня в БД при обновлении пишется).

                        Так все и работает, без нареканий.
                        Вот прямая ссылка на картинку webstartpage.ru/assets/components/phpthumbof/cache/8205d9aae8a4a5bdcfa5a22d6c99b20b.6d51640cbf897f1de7d609fd986018d9.jpg?1319860380
                          0
                          Когда обновляется файл с картинкой, то меняется дата его модификации и nginx на основании этого отдает картинку (а не 304) при запросе от браузера if-modified-since.
                            +3
                            Nginx то отдает, а броузер свою копию подсовывает. Причем, если открыть картинку в новом окне, отдельно и нажать f5 — броузер показывает новую версию =)

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

                            И кстати, последняя версия phpthumbof (1.2.2) Revo как то совсем круто кэширует — откатился на 1.2.0.
                  +1
                  Фильтр вывода работает при рендеренге страницы. То есть — при совмещении контента и шаблона.
                  На экран вы получаете уже готовую страницу с обработанными превьюшками.

                  Все картинки кэшируются, конечно.
                  0
                  TV параметр не обязателен. Можно работать с изображением просто через input.

                  Я делаю вот так, с обычными ссылками:

                  < img src='[[+id:input=`/inc/img/favorites/[[+img]]`:phpthumbof=`w=200&h=112&zc=1`]]?[[+updated:strtotime]]' alt='' title='' width='200' height='112' class='small' / >

                  id здесь просто для начала работы фильтра, дальше путь к картинке и placeholder. Как видно — они запихиваются через фильтр input, и к нему уже применяется phpthumbof. Также добавлено время обновления картинки, для борьбы с кэшем броузера.

                  Если интересно, как это все работает — вот, можно потыкать — webstartpage.ru
                    0
                    Подскажите. Делаю фильтрацию фотки по вашему примеру через чанк.


                    Вот таким образом вызываю [[$img200?&gallery=`469` &img=`002`]]

                    Но переменные gallery и img не подставляются. Просто пропуск.
                    Но если я в любом месте чанка добавляю переменные, nо все срабатывает. Добавить можно как угодно
                    можно как комментарий.
                    или alt='[[+gallery]] [[+img]]' — или так к тегу img.

                    Подскажите в чем проблема?
                      0
                      Вижу 2 варианта:
                      1. Кэширование. Попробуйте [[!$…
                      2. Порядок обработки переменных. Тут нужно разбираться. У Эво была такая пробема, когда phx при определенных условиях «съедал» плейсхолдеры.
                        0
                        забыл добавить у меня Revo.
                        1ый вариант сработал. А можно объяснить, почему. Я понял, что восклицательный знак задает моему чанку кешируемость. В последующие вызовах код обрабатываться не будет. Но как это повлияло на вывод переменных? Я не пойму.
                          0
                          Наоборот, чанк с! НЕ кэшируется. И обрабатывает все переданные переменные каждый раз.

                          Иначе, после первой обработки вывод берется из кэша и на смену переменных ему начхать.
                            0
                            Да, точно я перепутал.
                            А то что он не будет кешироватся, не повлияет на скорость работы?

                            А по поводу переменных. Они и не меняются. Их просто нет. Место них пустое место.

                            Да у меня есть предлоложение что это из-за двойных скобок


                            конструкция [[++site_url]]assets/gallery/[[+gallery]]/[[+img]].jpg выводиться без проблем.
                              0
                              Вы что-то путаете.

                              [[$ — это работа с чанком

                              [[+ — это работа с плейсхолдером. Плейсхолдеры находятся внутри чанков, страниц, шаблонов.

                              Если вы вызываете чанк с параметрами — то они превращаются в плейсхолдеры внутри него.
                              Вот здесь пример: rtfm.modx.com/display/revolution20/Chunks

                              Вот мой вызов: [[+id:input=`/inc/img/favorites/[[+img]]`:phpthumbof=`w=200&h=112&zc=1`]]
                              Вот ваш: [[$img200?&gallery=`469` &img=`002`]]

                              Вы видите, что я работаю с плейсхолдером, а вы с чанком? Понимаете ли вы разницу?

                              Передавать значения для плейсхолдеров при вызове чанка в вашем случае не имеет смысла, так что делайте как работает — [[++site_url]]assets/gallery/[[+gallery]]/[[+img]].jpg
                                0
                                Спасибо. Понял где я не до понимал систему.
                                У меня получается я плейсходер вызываю через чанк.

                                Приблизительно понял. Но надеюсь в процессе дальнейшей работы и изучения разберусь более детально.

                                Спасибо вам за статьи на modx-cms очень полезные.
                    0
                    Как то я пост прослоупочил( Плагин как то попробовал, что то там не заработало, и я про него забыл. Прочитал статью, и понял что 3 месяца я переодически занимался полной ерундой. Автору огромное спасибо. Но вот кое что омрачает мою радость. У меня почему то работает исключительно в виде отдельного вызова,

                    [[!phpthumbof? &input=`[[+filename]]` &options=`***`]]

                    и совершенно не хочет работать как фильтр

                    [[*TvNamephpthumbof=`***`]]

                    Может быть кто-нибудь подскажет, в чем может быть причина?
                      0
                      разобрался. Невнимательно статью читал. Вывод стоял — Image, а нужно — строка.
                      0
                      автору респект, буду юзать — даже круче чем DirectResize 0.9 (кто помнит)
                        0
                        А куда нужно класть .ttf шрифт? Просто указать путь на сервере до него? А то шрифт по-умолчанию не понимает кириллицу.
                          0
                          А можно ли сделать что бы редактировались изображения только большого размера, а если меньше определенных размеров оставлялись без изменений.

                          Only users with full accounts can post comments. Log in, please.