Wijzig het formaat van afbeeldingen direct met Nginx en LuaJIT (OpenResty)

Al geruime tijd geïnspireerd door het artikel Onmiddellijk het formaat van afbeeldingen aanpassen het formaat van de afbeelding is geconfigureerd met behulp van ngx_http_image_filter_module en alles werkte zoals het zou moeten. Maar er ontstond een probleem toen de manager afbeeldingen met exacte afmetingen moest ontvangen om naar bepaalde services te kunnen uploaden, omdat... dit waren hun technische vereisten. Als we bijvoorbeeld een originele afbeelding van formaat hebben 1200 × 1200, en bij het wijzigen van het formaat schrijven we zoiets als ?formaat wijzigen=600×400, dan krijgen we een proportioneel verkleind beeld langs de kleinste rand, grootte 400 × 400. Ook is het onmogelijk om een ​​beeld met een hogere resolutie (upscale) te verkrijgen. Die. ?formaat wijzigen=1500×1500 geeft hetzelfde beeld terug 1200 × 1200

Dit artikel kwam te hulp OpenResty: van NGINX een volwaardige applicatieserver maken om te begrijpen hoe Nginx met Lua en de bibliotheek zelf voor Lua werkt isage/lua-imagick - Lua pure-c-bindingen met ImageMagick. Waarom is voor deze oplossing gekozen, en niet voor bijvoorbeeld iets in Python - omdat het snel en gemakkelijk is. Je hoeft niet eens bestanden aan te maken, alles klopt in de Nginx-configuratie (optioneel).

Dus wat hebben we nodig

Er zullen voorbeelden worden gegeven op basis van Debian.

Nginx en nginx-extra's installeren

apt-get update
apt-get install nginx-extras

LuaJIT installeren

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

Imagemagick installeren

apt-get -y install imagemagick

en bibliotheken toverstaf ernaar toe, in mijn geval voor versie 6

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

Lua-imagick bouwen

We klonen de repository (of nemen de zip en pakken deze uit)

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

Als alles goed is gegaan, kun je Nginx configureren.

Ik zal een voorbeeld geven van de configuratie van de backend-host, die in feite verantwoordelijk is voor het wijzigen van de grootte. Het wordt geproxyd door de frontserver, ook met Nginx, waar caching gedurende een bepaalde periode (dagen) en andere dingen plaatsvindt.

nginx backend-configuratie

# 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
    }
}

Wat nodig was (de afbeelding langs de randen uitbreiden) gebeurt met behulp van img:extent() en wordt gedefinieerd met behulp van de parameter resize ondertekend + aan het einde.

De volgende opties zijn beschikbaar:

  • BxH (Behoud de beeldverhouding, gebruik een hogere afmeting)
  • BxH^ (Behoud de beeldverhouding, gebruik een lagere afmeting (bijsnijden))
  • BxH! (Negeer de beeldverhouding)
  • BxH+ (Behoud de beeldverhouding, voeg zijranden toe)

Overzichtstabel met resultaten voor het wijzigen van de grootte

Uri-parameter opvragen
Uitvoerbeeldgrootte

?formaat wijzigen=400×200
200 × 200

?formaat wijzigen=400×200^
400 × 400

?formaat wijzigen=400×200!
400×200 (niet proportioneel)

?formaat wijzigen=400×200+
400×200 (proportioneel)

Wijzig het formaat van afbeeldingen direct met Nginx en LuaJIT (OpenResty)

Totaal

Gezien de kracht en eenvoud van deze aanpak kun je dingen implementeren met behoorlijk complexe logica, bijvoorbeeld door watermerken toe te voegen of autorisatie met beperkte toegang te implementeren. Om de mogelijkheden van de API voor het werken met afbeeldingen te ontdekken, kunt u de bibliotheekdocumentatie raadplegen isage/lua-imagick

Bron: www.habr.com

Voeg een reactie