Перейти к содержанию

jpeg: Модуль фильтрации JPEG для NGINX

Установка на Debian/Ubuntu

Эти документы применимы к APT пакету nginx-module-jpeg, предоставленном репозиторием GetPageSpeed Extras.

  1. Настройте APT репозиторий, как описано в Настройка APT репозитория.
  2. Установите модуль:
sudo apt-get update
sudo apt-get install nginx-module-jpeg

Warning

Этот модуль еще не опубликован под именем nginx-module-jpeg в APT репозиториях. Следите за обновлениями или напишите на support@getpagespeed.com, чтобы запросить его.


Модуль фильтрации Nginx для добавления наложений на JPEG-файлы в реальном времени с помощью libmodjpeg.

С помощью libmodjpeg вы можете наложить (маскированное) изображение на существующий JPEG с максимальным сохранением без потерь. Изменения в JPEG происходят только там, где применяется наложенное изображение. Все модификации происходят в DCT-домене, таким образом, JPEG декодируется и кодируется без потерь.

Типичные использования

Этот модуль фильтра может добавлять наложения (например, логотип, визуальный водяной знак) на JPEG-файлы в момент их запроса.

Несколько идей:

  • Допустим, вы фотограф и у вас есть галерея изображений на вашем сайте. Не прибегая к жесткому кодированию вашего логотипа (бренда, водяного знака и т. д.) в этих изображениях, вы можете применить его в момент запроса изображения. Когда вы обновляете свой логотип, просто обновите конфигурацию nginx, и всё готово. Нет необходимости повторно обрабатывать все ваши изображения.
  • У вас есть интернет-магазин с тысячами изображений товаров. Настроив только nginx, вы можете добавить свой логотип ко всем изображениям товаров. Вам не нужно обрабатывать все изображения товаров.
  • У вас есть платный сервис. Добавьте водяной знак ко всем изображениям, если пользователь не подписан. Если пользователь подписан, не применяйте водяной знак или просто разместите небольшой логотип на изображениях, не касаясь оригинальных изображений.
  • На вашем сайте зарегистрированные пользователи могут загружать изображения. Добавьте аватар пользователя к изображению, которое загрузил пользователь, не обрабатывая его после загрузки. Если пользователь изменяет свой аватар, все его изображения автоматически обновятся с новым аватаром.

Попробуйте это

Чтобы попробовать этот модуль фильтрации, загрузите образ Docker

docker pull ioppermann/modjpeg-nginx:latest

Контейнер Docker открывает TCP-порт 80 и ожидает директорию с изображениями, смонтированную в /images, например:

docker run -it --rm --name=modjpeg-nginx \
   --mount type=bind,src=$PWD/images,dst=/images,readonly \
   -p 8080:80 \
   ioppermann/modjpeg-nginx:latest

Теперь вы можете перейти по http://localhost:8080/ и кликнуть на перечисленные изображения. Логотип modjpeg будет применен в верхнем левом углу. По умолчанию фильтр обрабатывает только изображения, размером меньше 10MB. Остановите контейнер, нажав Ctrl-c.

Фильтр можно управлять с помощью этих переменных окружения:

Имя По умолчанию Описание
MJ_GRACEFUL on См. jpeg_filter_graceful
MJ_BUFFER 10M См. jpeg_filter_buffer
MJ_MAX_PIXEL 0 См. jpeg_filter_max_pixel
MJ_DROPON_ALIGN "top left" См. jpeg_filter_dropon_align
MJ_DROPON_OFFSET "0 0" См. jpeg_filter_dropon_offset
MJ_DROPON_FILE "/usr/local/nginx/conf/dropon.png" См. jpeg_filter_dropon_file

Следующий пример позволит обрабатывать изображения размером до 150 мегапикселей (MJ_MAX_PIXEL) и 100 МБ по размеру файла (MJ_BUFFER). Логотип будет размещен в правом нижнем углу (MJ_DROPON_ALIGN) с смещением -15 пикселей по горизонтали и вертикали (MJ_DROPON_OFFSET).

docker run -it --rm --name=modjpeg-nginx \
   --mount type=bind,src=$PWD/images,dst=/images,readonly \
   -p 8080:80 \
   -e MJ_MAX_PIXEL=150000000 \
   -e MJ_BUFFER=100M \
   -e MJ_DROPON_ALIGN="bottom right" \
   -e MJ_DROPON_OFFSET="-15 -15" \
   ioppermann/modjpeg-nginx:latest

Для изменения логотипа вы можете смонтировать дополнительный объем или поместить его в уже смонтированную директорию, например:

docker run -it --rm --name=modjpeg-nginx \
   --mount type=bind,src=$PWD/images,dst=/images,readonly \
   -p 8080:80 \
   -e MJ_DROPON_FILE="/images/logo.png" \
   ioppermann/modjpeg-nginx:latest

Клонирование и установка libmodjpeg

git clone https://github.com/ioppermann/libmodjpeg.git cd libmodjpeg cmake . make make install cd ..

Клонирование modjpeg-nginx

git clone https://github.com/ioppermann/modjpeg-nginx.git

Скачивание и установка nginx

wget 'http://nginx.org/download/nginx-1.15.1.tar.gz' tar -xvzf nginx-1.15.1.tar.gz cd nginx-1.15.1

Настроить как статический модуль, или ...

./configure --add_module=../modjpeg-nginx

... настроить как динамический модуль (начиная с nginx 1.9.11)

./configure --add_dynamic_module=../modjpeg-nginx

Если библиотека libmodjpeg не найдена, добавьте, например, '--with-ld-opt=-L/usr/local/lib' к

параметрам конфигурации, если она была установлена в /usr/local/lib

Вы также можете использовать другие параметры './configure', которые используются

в вашей текущей сборке nginx. Проверьте вывод 'nginx -V'.

make make install

Если вы настроили modjpeg-nginx как динамический модуль, вам нужно загрузить модуль в начале конфигурации

```nginx
...
load_module modules/ngx_http_jpeg_filter_module.so;
...

Синопсис

   ...

   location /gallery {
      # включить модуль фильтра JPEG
      jpeg_filter on;

      # ограничить размеры изображений до 9 мегапикселей
      jpeg_filter_max_pixel 9000000;

      # ограничить размер файлов изображений до 5 мегабайт
      jpeg_filter_buffer 5M;

      # выдавать изображения без изменений, если одно из ограничений применимо
      jpeg_filter_graceful on;

      # пикселизировать изображение
      jpeg_filter_effect pixelate;

      # добавить маскированный логотип в правом нижнем углу
      # на расстоянии 10 пикселей от края
      jpeg_filter_dropon_align bottom right;
      jpeg_filter_dropon_offset -10 -10;
      jpeg_filter_dropon_file /path/to/logo.jpg /path/to/mask.jpg;
   }

   ...

Или используйте его с ngx_http_lua_module от OpenResty и PNG логотипом:

   ...

   location /gallery {
      set_by_lua_block $valign {
         local a = { 'top', 'center', 'bottom' }
         return a[math.random(#a)]
      }

      set_by_lua_block $halign {
         local a = { 'left', 'center', 'right' }
         return a[math.random(#a)]
      }

      # включить модуль фильтра JPEG
      jpeg_filter on;

      # ограничить размеры изображений до 9 мегапикселей
      jpeg_filter_max_pixel 9000000;

      # ограничить размер файлов изображений до 5 мегабайт
      jpeg_filter_buffer 5M;

      # выдавать изображения без изменений, если одно из ограничений применимо
      jpeg_filter_graceful on;

      # пикселизировать изображение
      jpeg_filter_effect pixelate;

      # добавить логотип в случайном положении
      jpeg_filter_dropon_align $valign $halign;
      jpeg_filter_dropon_file /path/to/logo.png;
   }

   ...

Или сгенерируйте логотип с помощью Lua-GD:

http {
   ...
   ...
   server {
      ...
      location /gallery {
          set_by_lua_block $logobytestream {
              local gd = require "gd"

              local im = gd.create(210, 70)
              local white = im:colorAllocate(255, 255, 255)
              local black = im:colorAllocate(0, 0, 0)
              im:filledRectangle(0, 0, 140, 80, white)
              im:string(gd.FONT_LARGE, 10, 10, "Hello modjpeg", black)
              im:string(gd.FONT_LARGE, 10, 40, os.date("%c"), black);
              return im:jpegStr(85)
          }

          # включить модуль фильтра JPEG
          jpeg_filter on;

          # ограничить размеры изображений до 9 мегапикселей
          jpeg_filter_max_pixel 9000000;

          # ограничить размер файлов изображений до 5 мегабайт
          jpeg_filter_buffer 5M;

          # выдавать изображения без изменений, если одно из ограничений применимо
          jpeg_filter_graceful on;

          # пикселизировать изображение
          jpeg_filter_effect pixelate;

          # добавить сгенерированный логотип в правом нижнем углу
          # на расстоянии 10 пикселей от края
          jpeg_filter_dropon_align bottom right;
          jpeg_filter_dropon_offset -10 -10;
          jpeg_filter_dropon_memory $logobytestream;
      }
      ...
   }
   ...
}

Директивы

jpeg_filter

Синтаксис: jpeg_filter on | off

По умолчанию: jpeg_filter off

Контекст: location

Включает модуль фильтрации JPEG.

Эта директива по умолчанию отключена.

jpeg_filter_max_pixel

Синтаксис: jpeg_filter_max_pixel pixel

По умолчанию: 0

Контекст: http, server, location

Максимальное количество пикселей в изображении для обработки. Если изображение имеет больше пикселей (ширина * высота), чем pixel, фильтр JPEG вернет "415 Unsupported Media Type". Установите jpeg_filter_graceful в on, чтобы доставить изображение без изменений. Установите максимальное количество пикселей в 0, чтобы игнорировать размеры изображения.

Эта директива по умолчанию установлена в 0.

jpeg_filter_buffer

Синтаксис: jpeg_filter_buffer size

По умолчанию: 2M

Контекст: http, server, location

Максимальный размер файла изображения для обработки. Если размер файла больше size, фильтр JPEG вернет "415 Unsupported Media Type". Установите jpeg_filter_graceful в on, чтобы доставить изображение без изменений.

Эта директива по умолчанию установлена в 2 мегабайта.

jpeg_filter_optimize

Синтаксис: jpeg_filter_optimize on | off

По умолчанию: off

Контекст: http, server, location

При доставке оптимизирует таблицы Хаффмана изображения.

Эта директива по умолчанию отключена.

jpeg_filter_progressive

Синтаксис: jpeg_filter_progressive on | off

По умолчанию: off

Контекст: http, server, location

При доставке включает прогрессивное кодирование изображения.

Эта директива по умолчанию отключена.

jpeg_filter_arithmetric

Синтаксис: jpeg_filter_arithmetric on | off

По умолчанию: off

Контекст: http, server, location

При доставке включает арифметическое кодирование изображения. Это переопределит директиву jpeg_filter_optimize. Арифметическое кодирование обычно не поддерживается браузерами.

Эта директива по умолчанию отключена.

jpeg_filter_graceful

Синтаксис: jpeg_filter_graceful on | off

По умолчанию: off

Контекст: http, server, location

Позволяет доставлять неизмененное изображение в случае, если директивы jpeg_filter_max_width, jpeg_filter_max_height или jpeg_filter_buffer приведут к ошибке "415 Unsupported Media Type".

Эта директива по умолчанию отключена.

jpeg_filter_effect

Синтаксис: jpeg_filter_effect grayscale | pixelate

Синтаксис: jpeg_filter_effect darken | brighten value

Синтаксис: jpeg_filter_effect tintblue | tintyellow | tintred | tintgreen value

По умолчанию: -

Контекст: location

Применяет эффект к изображению.

grayscale удалит все цветовые компоненты из изображения. Это применимо только к изображениям в цветовом пространстве YCbCr.

pixelate пикселизирует изображение блоками размером 8x8 пикселей, устанавливая коэффициенты AC во всех компонентах в 0.

darken затемняет изображение, уменьшая коэффициенты DC в компоненте Y на value. Это применимо только к изображениям в цветовом пространстве YCbCr.

brighten осветляет изображение, увеличивая коэффициенты DC в компоненте Y на value. Это применимо только к изображениям в цветовом пространстве YCbCr.

tintblue придает изображению синий оттенок, увеличивая коэффициенты DC в компоненте Cb на value. Это применимо только к изображениям в цветовом пространстве YCbCr.

tintyellow придает изображению желтый оттенок, уменьшая коэффициенты DC в компоненте Cb на value. Это применимо только к изображениям в цветовом пространстве YCbCr.

tintred придает изображению красный оттенок, увеличивая коэффициенты DC в компоненте Cr на value. Это применимо только к изображениям в цветовом пространстве YCbCr.

tintgreen придает изображению зеленый оттенок, уменьшая коэффициенты DC в компоненте Cr на value. Это применимо только к изображениям в цветовом пространстве YCbCr.

Эта директива по умолчанию не установлена.

Все параметры могут содержать переменные.

jpeg_filter_dropon_align

Синтаксис: jpeg_filter_dropon_align [top | center | bottom] [left | center | right]

По умолчанию: center center

Контекст: location

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

Эта директива должна быть установлена перед jpeg_filter_dropon, чтобы оказать влияние на наложение.

Эта директива по умолчанию применяет наложение в центре изображения.

Все параметры могут содержать переменные.

jpeg_filter_dropon_offset

Синтаксис: jpeg_filter_dropon_offset vertical horizontal

По умолчанию: 0 0

Контекст: location

Смещает наложение на vertical и horizontal пикселей от выравнивания, заданного директивой jpeg_filter_dropon_align. Используйте отрицательное значение, чтобы переместить наложение вверх или влево, и положительное значение, чтобы переместить наложение вниз или вправо.

Эта директива должна быть установлена перед jpeg_filter_dropon, чтобы оказать влияние на наложение.

Эта директива по умолчанию не применяет смещение.

Все параметры могут содержать переменные.

jpeg_filter_dropon_file

Синтаксис: jpeg_filter_dropon_file image

Синтаксис: jpeg_filter_dropon_file image mask

По умолчанию: -

Контекст: location

Применяет наложение к изображению. Наложение задается путем указания пути к JPEG или PNG изображению для image и, при необходимости, пути к JPEG изображению для mask. Если маска не предоставлена, изображение будет применено без полупрозрачности. Если предоставлена маска, будет использоваться только компонент яркости. Для маски черный цвет означает полную прозрачность, а белый – полную непрозрачность. Любые значения между ними будут смешивать нижележащее изображение и наложение соответственно. Если image является путем к PNG, маска будет проигнорирована.

Эта директива по умолчанию не установлена.

Все параметры могут содержать переменные.

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

PNG файлы в качестве наложения поддерживаются только в том случае, если libmodjpeg была скомпилирована с поддержкой PNG.

jpeg_filter_dropon_memory

Синтаксис: jpeg_filter_dropon_memory $image

Синтаксис: jpeg_filter_dropon_memory $image $mask

По умолчанию: -

Контекст: location

Применяет наложение к изображению. Наложение задается переменной, содержащей поток данных JPEG или PNG для $image, и, при необходимости, переменной для потока данных JPEG для $mask. Если маска не предоставлена, изображение будет применено без полупрозрачности. Если предоставлена маска, будет использоваться только компонент яркости. Для маски черный цвет означает полную прозрачность, а белый – полную непрозрачность. Любые значения между ними будут смешивать нижележащее изображение и наложение соответственно. Если $image является PNG, маска будет проигнорирована.

Эта директива по умолчанию не установлена.

Все параметры должны быть переменными.

Наложение всегда загружается во время обработки запроса. После обработки запроса наложение будет выгружено.

Потоки данных PNG в качестве наложения поддерживаются только в том случае, если libmodjpeg была скомпилирована с поддержкой PNG.

Заметки

Директивы jpeg_filter_effect, jpeg_filter_dropon_align, jpeg_filter_dropon_offset и jpeg_filter_dropon применяются в порядке их появления в файле конфигурации nginx, т.е. имеет значение, примените ли вы сначала эффект, а затем добавьте наложение или наоборот. В первом случае наложение не будет затронуто эффектом, а во втором случае эффект также будет применен к наложению.

Благодарности

Этот модуль сильно вдохновлен модулем фильтрации изображений nginx с идеями из "Руководства Эмиллера по разработке модулей Nginx" и руководства по разработке nginx.