Превью картинок с ngx_http_image_filter_module
Зачастую на мультимедийных сайтах существует задача выдавать картинки (часто пользовательское фото) в различных размерах (thumbnails). Причем, в большинстве случаев приходится поддерживать несколько размерных версий картинок (например, пользовательское фото vkontakte.ru имеет 3 различные размерные версии).
Один из примеров построения системы отдачи изображений описан в статье “Отдача и ресайзинг фотографий“. Тем не менее, существует несколько альтернативных вариантов. Подробнее об одном из них в этой статье.
Создатель одного из самых популярных в мире серверов для высоконагруженых проектов (речь идет о nginx) порадовал новым модулем “ngx_http_image_filter_module”. Модуль позволяет решать задачу ресайзинга картинок напрямую через Web сервер (без дополнительных звеньев). Как все это выглядит, и что для этого нужно сделать?
Установка
Качаем самую последнюю версию тут.
Для начала, Вам понадобиться установить libgd:
sudo apt-get install libgd2-xpm-dev
По умолчанию, необходимый нам модуль не собирается, поэтому его нужно подключить на этапе конфигурации установки nginx:
./configure --with-http_image_filter_module make sudo make install
Конфигурация сервера
Теперь конфигурируем virtual host в nginx для обработки картинок. Пусть изображения хранятся в директории “/home/test/photos” и мы хотим показывать две размерных версии + оригинал. Правила такие:
-
- При запросе вида “example.com/a/<имя-картинки>” будем показывать версию 75х75, обрезанную по краям (т.е. всегда квадратную)
-
- “example.com/b/<имя-картинки>” – показываем версию, вписанную в квадрат 200×200
-
- “example.com/<имя-картинки>” – показываем оригинал изображения
Собственно наша конфигурация:
# Resizing server server { listen 8081; server_name localhost; # 'a' size, 75x75 with crop location /a/ { proxy_pass http://imageserver; # Backend image server image_filter crop 75 75; # Resize photo 75x75 and crop error_page 415 = /empty; # Handle error by /empty location } # 'b' size 200x200 location /b/ { proxy_pass http://imageserver; image_filter resize 200 200; # Resize photo 200x200 error_page 415 = /empty; } # Original image location / { proxy_pass http://imageserver; # Proxiing with no filtering } # Error handler location = /empty { empty_gif; # Respond with empty image } } # Backend image server server { listen 8082; server_name localhost; root /home/test/photos; rewrite ^/[ab]/(.*)$ /$1 last; } # Upstream upstream imageserver { server localhost:8082; }
Теперь, если у нас в папке “/home/test/photos” есть картинка с названием test.jpg, то протестировать работу сервера можно следующим образом:
-
- localhost:8081/test.jpg – покажет оригинальное изображение
-
- localhost:8081/a/test.jpg – покажет версию 75х75
-
- localhost:8081/b/test.jpg – покажет версию 200х200
Мы подняли сервер на порту 8081, который будет отдавать различные версии картинок. Для каждой версии – отдельная директива location. Что нас интересует – это директива image_filter. Мы использовали ее в двух вариантах:
-
- image_filter resize A B – уменьшает картинку пропорционально для вписывания в заданые размеры АхВ
-
- image_filter crop A B – уменьшает картинку и обрезает по краям большую е сторону таким образом, что-бы конечный размер точно соответствовал АхВ
Сервер, слушающий порт 8082, выдает изображения из папки “/home/test/photos“, причем переписывает путь, если есть префикс размера (/a/ или /b/) с помощью директивы rewrite. Для того, что-бы организовать бекенд сервер с порта 8082 мы использовали upstream.
В случае ошибки ресайзинга, модуль отдает ощибку 415, которую можно обработать. В нашем примере, в случае такой ошибки мы показываем пустой gif.
Модуль ресайзинга позволяет работать с форматами JPEG, GIF и PNG.
Документация по модулю ngx_http_image_filter_module.
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: