Ändern Sie die Größe von Bildern im laufenden Betrieb mit Nginx und LuaJIT (OpenResty).

Seit geraumer Zeit jetzt, durch den Artikel inspiriert Größe der Bilder auf der Fly , Ändern der Bildgröße mit ngx_http_image_filter_module eingerichtet wurden und alles funktionierte , wie es sollte. Es gab jedoch ein Problem, als der Manager Bilder mit exakten Größen für das Hochladen auf einige Dienste abrufen musste, weil Dies waren ihre technischen Anforderungen. Wenn wir beispielsweise ein Originalbild mit der Größe 1200 x 1200 haben und beim Ändern der Größe etwa " Größe ändern = 600 x 400" schreiben , erhalten wir am kleinsten Rand ein proportional verkleinertes Bild mit der Größe 400 x 400 . Es ist auch unmöglich, ein Bild mit einer höheren Auflösung (gehoben) zu erhalten. Jene. ? resize = 1500x1500 gibt das gleiche Bild zurück1200 x 1200


Ein OpenResty- Artikel kam zur Rettung: Wir verwandeln NGINX in einen vollwertigen Anwendungsserver, um zu verstehen, wie Nginx mit Lua und der Bibliothek für Lua isage / lua-imagick selbst zusammenarbeitet - Lua pure-c-Bindungen an ImageMagick. Warum eine solche Lösung gewählt wurde und nicht etwa etwas in Python - weil sie schnell und bequem ist. Sie müssen nicht einmal Dateien erstellen, in der Nginx-Konfiguration stimmt alles (optional).


Was brauchen wir also?


Beispiele werden basierend auf Debian gegeben.


Installieren Sie Nginx und Nginx-Extras


apt-get update
apt-get install nginx-extras

Installieren Sie LuaJIT


apt-get -y install lua5.1 luajit-5.1 libluajit-5.1-dev

Installieren Sie imagemagick


apt-get -y install imagemagick

und die magickwand- Bibliotheken dazu, in meinem Fall für Version 6


apt-cache search libmagickwand
apt-get -y install libmagickwand-6.q16-3 libmagickwand-6.q16-dev

Lua-Imagick bauen


Wir klonen das Repository (naja, oder nimm den Reißverschluss und packe ihn aus)


cd ~
git clone https://github.com/isage/lua-imagick.git
cd lua-imagick
mkdir build
cd build
cmake ..
make
make install

Wenn alles gut gegangen ist, können Sie Nginx konfigurieren.


backend , , , . Nginx, () . .


nginx backend config
# Backend image server
server {
    listen       8082;
    listen [::]:8082;
    set $files_root /var/www/example.lh/frontend/web;
    root $files_root;
    access_log off;
    expires 1d;

    location /files {
        #   
        set $w 700;
        set $h 700;
        set $q 89;

        #1-89 allowed
        if ($arg_q ~ "^([1-9]|[1-8][0-9])$") {
            set $q $arg_q;
        }

        if ($arg_resize ~ "([\d\-]+)x([\d\+\!\^]+)") {  
            set $w $1;
            set $h $2;
            rewrite  ^(.*)$   /resize/$w/$h/$q$uri     last;
        }

        rewrite  ^(.*)$   /resize/$w/$h/$q$uri     last;
    }

    location ~* ^/resize/([\d]+)/([\d\+\!\^]+)/([\d]+)/files/(.+)$ {
        default_type 'text/plain';

        set $w $1;
        set $h $2;
        set $q $3;
        set $fname $4;

        #     Lua    
        # content_by_lua_file /var/www/some.lua;
        # lua_code_cache off; #dev
        content_by_lua '
        local magick = require "imagick"
        local img = magick.open(ngx.var.files_root .. "/files/" .. ngx.var.fname)
        if not img then ngx.exit(ngx.HTTP_NOT_FOUND) end
        img:set_gravity(magick.gravity["CenterGravity"])

        if string.match(ngx.var.h, "%d+%+") then
            local h = string.gsub(ngx.var.h, "(%+)", "")
            resize = ngx.var.w .. "x" .. h
            --  png   
            img:set_bg_color(img:has_alphachannel() and "none" or img:get_bg_color())
            img:smart_resize(resize)
            img:extent(ngx.var.w, h)
        else
                img:smart_resize(ngx.var.w .. "x" .. ngx.var.h)
        end

        if ngx.var.arg_q then img:set_quality(ngx.var.q) end

        ngx.say(img:blob())
        ';
    }
}

# Upstream
upstream imageserver {
    server localhost:8082;
}

server {
    listen 80;
    server_name examaple.lh;

    #   jpg  png   imageserver
    location ~* ^/files/.+\.(jpg|png) {
        proxy_buffers 8 2m;
        proxy_buffer_size 10m;
        proxy_busy_buffers_size 10m;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_pass     http://imageserver;  # Backend image server
    }
}

, ( ) img:extent() resize + .


:


  • WxH (Keep aspect-ratio, use higher dimension)
  • WxH^ (Keep aspect-ratio, use lower dimension (crop))
  • WxH! (Ignore aspect-ratio)
  • WxH+ (Keep aspect-ratio, add side borders)


uri
?resize=400x200200x200
?resize=400x200^400x400
?resize=400x200!400x200 ( )
?resize=400x200+400x200 ()



Angesichts der Leistungsfähigkeit und Einfachheit dieses Ansatzes können Sie Dinge mit einer ziemlich komplizierten Logik implementieren, z. B. Wasserzeichen hinzufügen oder Berechtigungen mit eingeschränktem Zugriff implementieren. Informationen zu den Funktionen der API für die Arbeit mit Bildern finden Sie in der Dokumentation der isage / lua-imagick-Bibliothek


All Articles