Piltide suuruse muutmine reaalajas Nginx'i ja LuaJIT (OpenResty) abil

Juba on olnud, inspireerituna artiklist Piltide suuruse muutmine reaalajas oli seadistatud piltide suuruse muutmine kasutades ngx_http_image_filter_module ja kõik töötas nagu peab. Kuid tekkis üks probleem, kui juhatajale oli vaja saada täpsete mõõtmetega pilte mõnesse teenusesse, kuna need olid nende tehnilised nõuded. Näiteks, kui meil on originaalpilt mõõtmetega 1200×1200, ja kui me suuruse muutmisel kirjutame midagi sellist nagu ?resize=600×400, siis saame proportsionaalselt vähendatud pildi väikseima ääre järgi, mõõtmetega 400×400. Samuti ei ole võimalik saada pilti suuremas eraldusvõimes (upscale). See tähendab, et ?resize=1500×1500 tagastab kõik sama pildi 1200×1200

Abiks tuli artikkel OpenResty: muudetakse NGINX täiustatud rakendusserveriks aru saamiseks, kuidas Nginx töötab Lua'ga ja selle ise biblioteegiga Lua isage/lua-imagick — Lua puhtad C sidemed ImageMagick'iga. Miks valiti selline lahendus, mitte näiteks midagi Pythonis — kuna see on kiire ja mugav. Teie ei pea isegi lugema mingeid faile, kõik on otse Nginxi konfiguratsioonis (mitte kohustuslik).

Nii et, mida meil on vaja

Näidised põhinevad Debianil.

Nginxi ja nginx-extras'i installimine

apt-get update
apt-get install nginx-extras

LuaJIT'i installimine

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

ImageMagick'i installimine

apt-get -y install imagemagick

ja sellele raamatukogule magickwand minu juhul 6. versiooni jaoks

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

lua-imagick'i ehitamine

Kloonime hoidla (või võtame zip-faili ja pakkime lahti)

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

Kui kõik läks hästi, saab Nginxi seadistada.

Toon näite backend hosti konfiguratsioonist, mis tegelikult tegeleb suuruse muutmisega. See on Nginxi kaudu proksitud frontend serveri poolt, kus toimub vahemälu hoidmine teatud ajaks (üks päev) ja muud asjad.

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

See, mis oli vajalik (pildi laiendamine ääred) toimub kasutades img:extent() ja määratakse parameetri kaudu resize märkidega + lõpus.

Saadaval on järgmised parameetrid:

  • WxH (Hoia proportsiooni, kasuta kõrgemat mõõdet)
  • WxH^ (Hoia proportsiooni, kasuta madalamat mõõdet (crop))
  • WxH! (Ignoreeri proportsiooni)
  • WxH+ (Hoia proportsiooni, lisa külgpinnad)

Kokkuvõtte tabel suuruse muutmise tulemustest

Parameeter uri päringus
Väljundi pildi suurus

?resize=400×200
200×200

?resize=400×200^
400×400

?resize=400×200!
400×200 (Ei ole proportsioonis)

?resize=400×200+
400×200 (Proportsioonis)

Piltide suuruse muutmine reaalajas Nginx'i ja LuaJIT (OpenResty) abil

Kokkuvõte

Arvestades selle lähenemise kogu võimsust ja lihtsust, on võimalik teostada asju, millel on üsna keeruline loogika, näiteks lisada vesimärke või rakendada autentsust piiratud juurdepääsuga. Et teada saada API võimeid piltide töötlemiseks, saate tutvuda raamatukogu dokumentatsiooniga. isage/lua-imagick

Allikas: habr.com

Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster