Zum Inhalt

jpeg: NGINX JPEG-Filtermodul

Installation

Sie können dieses Modul in jeder RHEL-basierten Distribution installieren, einschließlich, aber nicht beschränkt auf:

  • RedHat Enterprise Linux 7, 8, 9 und 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 und Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-jpeg
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-jpeg

Aktivieren Sie das Modul, indem Sie Folgendes an den Anfang von /etc/nginx/nginx.conf hinzufügen:

load_module modules/ngx_http_jpeg_filter_module.so;

Dieses Dokument beschreibt nginx-module-jpeg v1.0.1 veröffentlicht am 04. Sep 2018.


Nginx-Filtermodul zum Hinzufügen von Overlays auf JPEGs zur Laufzeit mit libmodjpeg.

Mit libmodjpeg können Sie ein (maskiertes) Bild auf ein vorhandenes JPEG so verlustfrei wie möglich überlagern. Änderungen im JPEG erfolgen nur dort, wo das überlagerte Bild angewendet wird. Alle Modifikationen erfolgen im DCT-Bereich, sodass das JPEG verlustfrei dekodiert und kodiert wird.

Typische Anwendungen

Dieses Filtermodul kann Overlays (z.B. ein Logo, visuelles Wasserzeichen) auf JPEGs hinzufügen, wenn diese angefordert werden.

Einige Ideen:

  • Angenommen, Sie sind Fotograf und haben eine Bildergalerie auf Ihrer Website. Ohne Ihr Logo (Marke, Wasserzeichen, ...) fest in diese Bilder einzubetten, können Sie es im Moment der Anforderung des Bildes anwenden. Wann immer Sie Ihr Logo aktualisieren, aktualisieren Sie einfach die NGINX-Konfiguration und es ist erledigt. Es ist nicht notwendig, alle Ihre Bilder erneut zu verarbeiten.
  • Sie haben einen Online-Shop mit Tausenden von Produktbildern. Mit nur der Konfiguration von NGINX können Sie Ihr Logo zu allen Produktbildern hinzufügen. Sie müssen keine Produktbilder verarbeiten.
  • Sie haben einen kostenpflichtigen Dienst. Fügen Sie allen Bildern ein Wasserzeichen hinzu, wenn der Benutzer nicht abonniert ist. Wenn der Benutzer abonniert ist, wenden Sie das Wasserzeichen nicht an oder fügen Sie nur ein kleines Logo auf den Bildern hinzu, ohne die Originalbilder zu berühren.
  • Auf Ihrer Website können registrierte Benutzer Bilder hochladen. Fügen Sie das Avatar des Benutzers zu dem Bild hinzu, das das Bild hochgeladen hat, ohne es nach dem Hochladen zu verarbeiten. Wenn der Benutzer sein Avatar ändert, haben alle seine Bilder automatisch das neue Avatar.

Probieren Sie es aus

Um dieses Filtermodul auszuprobieren, ziehen Sie das Docker-Image

docker pull ioppermann/modjpeg-nginx:latest

Der Docker-Container exponiert den TCP-Port 80 und erwartet ein Verzeichnis mit Bildern, das auf /images gemountet ist, z.B.

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

Jetzt können Sie zu http://localhost:8080/ navigieren und auf die aufgelisteten Bilder klicken. Das modjpeg-Logo wird in der oberen linken Ecke angewendet. Standardmäßig werden nur Bilder verarbeitet, die kleiner als 10 MB sind. Stoppen Sie den Container, indem Sie Ctrl-c drücken.

Der Filter kann durch diese Umgebungsvariablen gesteuert werden:

Name Standard Beschreibung
MJ_GRACEFUL on Siehe jpeg_filter_graceful
MJ_BUFFER 10M Siehe jpeg_filter_buffer
MJ_MAX_PIXEL 0 Siehe jpeg_filter_max_pixel
MJ_DROPON_ALIGN "top left" Siehe jpeg_filter_dropon_align
MJ_DROPON_OFFSET "0 0" Siehe jpeg_filter_dropon_offset
MJ_DROPON_FILE "/usr/local/nginx/conf/dropon.png" Siehe jpeg_filter_dropon_file

Das folgende Beispiel erlaubt Bilder mit bis zu 150 Megapixel (MJ_MAX_PIXEL) und 100 MB Dateigröße (MJ_BUFFER). Das Logo wird in der unteren rechten Ecke platziert (MJ_DROPON_ALIGN) mit einem Offset von -15px horizontal und vertikal (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

Um das Logo zu ändern, können Sie ein zusätzliches Volume mounten oder es in das Verzeichnis legen, das Sie bereits mounten, z.B.

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

Klonen und installieren von libmodjpeg

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

Klonen von modjpeg-nginx

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

Herunterladen und Installieren von 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

Konfigurieren als statisches Modul, oder ...

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

... konfigurieren als dynamisches Modul (ab nginx 1.9.11)

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

Wenn die libmodjpeg-Bibliothek nicht gefunden wird, fügen Sie z.B. '--with-ld-opt=-L/usr/local/lib' zu

den Konfigurationsoptionen hinzu, wenn sie nach /usr/local/lib installiert wurde.

Sie möchten möglicherweise die anderen './configure'-Optionen verwenden, die in Ihrem aktuellen nginx-Build verwendet werden. Überprüfen Sie die Ausgabe von 'nginx -V'.

make make install

Wenn Sie modjpeg-nginx als dynamisches Modul konfiguriert haben, müssen Sie das Modul am Anfang der Konfiguration laden

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

Zusammenfassung

   ...

   location /gallery {
      # aktivieren Sie das jpeg-Filtermodul
      jpeg_filter on;

      # begrenzen Sie die Bildgrößen auf 9 Megapixel
      jpeg_filter_max_pixel 9000000;

      # begrenzen Sie die Bilddateigröße auf 5 Megabyte
      jpeg_filter_buffer 5M;

      # liefern Sie die Bilder unverändert, wenn eines der Limits gilt
      jpeg_filter_graceful on;

      # pixeln Sie das Bild
      jpeg_filter_effect pixelate;

      # fügen Sie ein maskiertes Logo in der unteren rechten Ecke hinzu
      # mit einem Abstand von 10 Pixeln vom Rand
      jpeg_filter_dropon_align bottom right;
      jpeg_filter_dropon_offset -10 -10;
      jpeg_filter_dropon_file /path/to/logo.jpg /path/to/mask.jpg;
   }

   ...

Oder verwenden Sie es mit OpenRestys ngx_http_lua_module und einem PNG-Logo:

   ...

   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)]
      }

      # aktivieren Sie das jpeg-Filtermodul
      jpeg_filter on;

      # begrenzen Sie die Bildgrößen auf 9 Megapixel
      jpeg_filter_max_pixel 9000000;

      # begrenzen Sie die Bilddateigröße auf 5 Megabyte
      jpeg_filter_buffer 5M;

      # liefern Sie die Bilder unverändert, wenn eines der Limits gilt
      jpeg_filter_graceful on;

      # pixeln Sie das Bild
      jpeg_filter_effect pixelate;

      # fügen Sie ein Logo an einer zufälligen Position hinzu
      jpeg_filter_dropon_align $valign $halign;
      jpeg_filter_dropon_file /path/to/logo.png;
   }

   ...

Oder generieren Sie ein Logo mit 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)
           }

       # aktivieren Sie das jpeg-Filtermodul
       jpeg_filter on;

           # begrenzen Sie die Bildgrößen auf 9 Megapixel
           jpeg_filter_max_pixel 9000000;

           # begrenzen Sie die Bilddateigröße auf 5 Megabyte
           jpeg_filter_buffer 5M;

           # liefern Sie die Bilder unverändert, wenn eines der Limits gilt
           jpeg_filter_graceful on;

           # pixeln Sie das Bild
           jpeg_filter_effect pixelate;

           # fügen Sie ein generiertes Logo in der unteren rechten Ecke hinzu
           # mit einem Abstand von 10 Pixeln vom Rand
           jpeg_filter_dropon_align bottom right;
           jpeg_filter_dropon_offset -10 -10;
           jpeg_filter_dropon_memory $logobytestream;
      }
      ...
   }
   ...
}

Direktiven

jpeg_filter

Syntax: jpeg_filter on | off

Standard: jpeg_filter off

Kontext: location

Aktivieren Sie das jpeg-Filtermodul.

Diese Direktive ist standardmäßig deaktiviert.

jpeg_filter_max_pixel

Syntax: jpeg_filter_max_pixel pixel

Standard: 0

Kontext: http, server, location

Maximale Anzahl von Pixeln im Bild, auf die zugegriffen werden soll. Wenn das Bild mehr Pixel (Breite * Höhe) als pixel hat, gibt der jpeg-Filter einen "415 Unsupported Media Type" zurück. Setzen Sie jpeg_filter_graceful auf on, um das Bild unverändert zu liefern. Setzen Sie die maximale Pixelanzahl auf 0, um die Bildabmessungen zu ignorieren.

Diese Direktive ist standardmäßig auf 0 gesetzt.

jpeg_filter_buffer

Syntax: jpeg_filter_buffer size

Standard: 2M

Kontext: http, server, location

Die maximale Dateigröße des Bildes, auf das zugegriffen werden soll. Wenn die Dateigröße größer als size ist, gibt der jpeg-Filter einen "415 Unsupported Media Type" zurück. Setzen Sie jpeg_filter_graceful auf on, um das Bild unverändert zu liefern.

Diese Direktive ist standardmäßig auf 2 Megabyte gesetzt.

jpeg_filter_optimize

Syntax: jpeg_filter_optimize on | off

Standard: off

Kontext: http, server, location

Optimieren Sie beim Liefern die Huffman-Tabellen des Bildes.

Diese Direktive ist standardmäßig deaktiviert.

jpeg_filter_progressive

Syntax: jpeg_filter_progressive on | off

Standard: off

Kontext: http, server, location

Aktivieren Sie beim Liefern die progressive Kodierung des Bildes.

Diese Direktive ist standardmäßig deaktiviert.

jpeg_filter_arithmetric

Syntax: jpeg_filter_arithmetric on | off

Standard: off

Kontext: http, server, location

Aktivieren Sie beim Liefern die arithmetische Kodierung des Bildes. Dies überschreibt die Direktive jpeg_filter_optimize. Arithmetische Kodierung wird von Browsern normalerweise nicht unterstützt.

Diese Direktive ist standardmäßig deaktiviert.

jpeg_filter_graceful

Syntax: jpeg_filter_graceful on | off

Standard: off

Kontext: http, server, location

Erlauben Sie die Lieferung des unveränderten Bildes, falls die Direktiven jpeg_filter_max_width, jpeg_filter_max_height oder jpeg_filter_buffer einen "415 Unsupported Media Type"-Fehler zurückgeben würden.

Diese Direktive ist standardmäßig deaktiviert.

jpeg_filter_effect

Syntax: jpeg_filter_effect grayscale | pixelate

Syntax: jpeg_filter_effect darken | brighten value

Syntax: jpeg_filter_effect tintblue | tintyellow | tintred | tintgreen value

Standard: -

Kontext: location

Wenden Sie einen Effekt auf das Bild an.

grayscale entfernt alle Farbkomponenten aus dem Bild. Dies gilt nur für Bilder im YCbCr-Farbraum.

pixelate pixelt das Bild in Blöcken von 8x8 Pixeln, indem die AC-Koeffizienten in allen Komponenten auf 0 gesetzt werden.

darken verdunkelt das Bild, indem die DC-Koeffizienten in der Y-Komponente um value verringert werden. Dies gilt nur für Bilder im YCbCr-Farbraum.

brighten hellt das Bild auf, indem die DC-Koeffizienten in der Y-Komponente um value erhöht werden. Dies gilt nur für Bilder im YCbCr-Farbraum.

tintblue färbt das Bild blau, indem die DC-Koeffizienten in der Cb-Komponente um value erhöht werden. Dies gilt nur für Bilder im YCbCr-Farbraum.

tintyellow färbt das Bild blau, indem die DC-Koeffizienten in der Cb-Komponente um value verringert werden. Dies gilt nur für Bilder im YCbCr-Farbraum.

tintred färbt das Bild rot, indem die DC-Koeffizienten in der Cr-Komponente um value erhöht werden. Dies gilt nur für Bilder im YCbCr-Farbraum.

tintgreen färbt das Bild grün, indem die DC-Koeffizienten in der Cr-Komponente um value verringert werden. Dies gilt nur für Bilder im YCbCr-Farbraum.

Diese Direktive ist standardmäßig nicht gesetzt.

Alle Parameter können Variablen enthalten.

jpeg_filter_dropon_align

Syntax: jpeg_filter_dropon_align [top | center | bottom] [left | center | right]

Standard: center center

Kontext: location

Richten Sie das Dropon im Bild aus. Verwenden Sie die Direktive jpeg_filter_dropon_offset, um das Dropon von der Ausrichtung zu versetzen.

Diese Direktive muss vor jpeg_filter_dropon gesetzt werden, um eine Wirkung auf das Dropon zu haben.

Diese Direktive wird standardmäßig das Dropon in der Mitte des Bildes anwenden.

Alle Parameter können Variablen enthalten.

jpeg_filter_dropon_offset

Syntax: jpeg_filter_dropon_offset vertical horizontal

Standard: 0 0

Kontext: location

Versetzen Sie das Dropon um vertical und horizontal Pixel von der Ausrichtung, die mit der Direktive jpeg_filter_dropon_align angegeben wurde. Verwenden Sie einen negativen Wert, um das Dropon nach oben oder links zu verschieben, und einen positiven Wert, um das Dropon nach unten oder rechts zu verschieben.

Diese Direktive muss vor jpeg_filter_dropon gesetzt werden, um eine Wirkung auf das Dropon zu haben.

Diese Direktive wird standardmäßig keinen Offset anwenden.

Alle Parameter können Variablen enthalten.

jpeg_filter_dropon_file

Syntax: jpeg_filter_dropon_file image

Syntax: jpeg_filter_dropon_file image mask

Standard: -

Kontext: location

Wenden Sie ein Dropon auf das Bild an. Das Dropon wird durch einen Pfad zu einem JPEG- oder PNG-Bild für image und optional einen Pfad zu einem JPEG-Bild für mask angegeben. Wenn kein Maskenbild bereitgestellt wird, wird das Bild ohne Transluzenz angewendet. Wenn ein Maskenbild bereitgestellt wird, wird nur die Helligkeitskomponente verwendet. Für die Maske bedeutet schwarz vollständig transparent und weiß vollständig opak. Alle Werte dazwischen mischen das zugrunde liegende Bild und das Dropon entsprechend. Wenn image ein Pfad zu einem PNG ist, wird die Maske ignoriert.

Diese Direktive ist standardmäßig nicht gesetzt.

Alle Parameter können Variablen enthalten.

Wenn keiner der Parameter Variablen enthält, wird das Dropon beim Laden der Konfiguration geladen. Wenn mindestens ein Parameter Variablen enthält, wird das Dropon während der Verarbeitung der Anfrage geladen. Nach der Verarbeitung der Anfrage wird das Dropon entladen.

PNG-Dateien als Dropon werden nur unterstützt, wenn libmodjpeg mit PNG-Unterstützung kompiliert wurde.

jpeg_filter_dropon_memory

Syntax: jpeg_filter_dropon_memory $image

Syntax: jpeg_filter_dropon_memory $image $mask

Standard: -

Kontext: location

Wenden Sie ein Dropon auf das Bild an. Das Dropon wird durch eine Variable, die einen JPEG- oder PNG-Bild-Bytestream für $image hält, und optional eine Variable für einen JPEG-Bild-Bytestream für $mask angegeben. Wenn kein Maskenbild bereitgestellt wird, wird das Bild ohne Transluzenz angewendet. Wenn ein Maskenbild bereitgestellt wird, wird nur die Helligkeitskomponente verwendet. Für die Maske bedeutet schwarz vollständig transparent und weiß vollständig opak. Alle Werte dazwischen mischen das zugrunde liegende Bild und das Dropon entsprechend. Wenn $image ein PNG ist, wird die Maske ignoriert.

Diese Direktive ist standardmäßig nicht gesetzt.

Alle Parameter werden als Variablen erwartet.

Das Dropon wird immer während der Verarbeitung der Anfrage geladen. Nach der Verarbeitung der Anfrage wird das Dropon entladen.

PNG-Bytestreams als Dropon werden nur unterstützt, wenn libmodjpeg mit PNG-Unterstützung kompiliert wurde.

Hinweise

Die Direktiven jpeg_filter_effect, jpeg_filter_dropon_align, jpeg_filter_dropon_offset und jpeg_filter_dropon werden in der Reihenfolge angewendet, in der sie in der NGINX-Konfigurationsdatei erscheinen, d.h. es macht einen Unterschied, ob Sie zuerst einen Effekt anwenden und dann ein Dropon hinzufügen oder umgekehrt. Im ersteren Fall bleibt das Dropon vom Effekt unberührt, und im letzteren Fall wird der Effekt auch auf das Dropon angewendet.

Danksagung

Dieses Modul ist stark inspiriert vom NGINX-Bildfiltermodul mit Erkenntnissen aus "Emiller’s Guide To Nginx Module Development" und dem NGINX-Entwicklungsleitfaden.

GitHub

Sie finden möglicherweise zusätzliche Konfigurationstipps und Dokumentationen für dieses Modul im GitHub-Repository für nginx-module-jpeg.