Piltide staatiline suuruse muutmine Nginx-i ja LuaJIT (OpenResty) abil

Juba mõnda aega tagasi, olles inspireeritud 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 juhile oli vaja saada pilte täpsete mõõtmetega teatud teenustele üleslaadimiseks, kuna need olid nende tehnilised nõuded. Näiteks, kui meil on originaalpilt suurusega 1200×1200, ja suuruse muutmisel kirjutame midagi sellist nagu ?resize=600×400, saame proportsionaalselt vähendatud pildi väikseima serva järgi, suurusega 400×400. Samuti ei ole võimalik saada pilti suurema eraldusvõimega (upscale). St, ?resize=1500×1500 tagastab sama pildi 1200×1200

Abi tuli artiklist OpenResty: muudame NGINX täielikuks rakenduste serveriks aru saamiseks, kuidas Nginx töötab Lua'ga ja ise raamistik Lua jaoks isage/lua-imagick — Lua puhas-c sidekood ImageMagick'ile. Miks valiti selline lahendus, mitte näiteks midagi Pythonis — sest see on kiire ja mugav. Teile ei ole isegi vaja luua mingeid faile, kõik toimub otse Nginxi konfingis (mitte kohustuslik).

Nii et, mida me vajame

Näiteid tutvustatakse Debianil.

Nginxi ja nginx-extras paigaldamine

apt-get update
apt-get install nginx-extras

LuaJIT'i paigaldamine

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

Imagemagick'i paigaldamine

apt-get -y install imagemagick

ja raamatukogud magickwand temal, minu juhul versiooni 6 jaoks

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

lua-imagicki koostamine

Kloonime reposiidi (või saame zip ja ekstraktime selle)

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.

Tuletan meelde backend-hosti konfiguratsiooni näidet, mis tegeleb tegelikult pildi suurendamisega. See edastatakse frontend-serverisse ka Nginxi kaudu, kus toimub vahemälu hoidmine teatud ajaks (24 tunniks) ja muud sarnased toimingud.

nginx backend konfiguratsioon

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

Tegelikult vajalik (pildi laiendamine külgedelt) toimub järgmise abil img:extent() ja määratakse parameetri abil resize märgiga + lõpus.

Saadaval on järgmised parameetrid:

  • WxH (hoia kuvasuhte, kasuta suuremat mõõtu)
  • WxH^ (hoia kuvasuhte, kasuta väiksemat mõõtu (lõika))
  • WxH! (tähelepanu mitte kuvasuhtele)
  • WxH+ (hoia kuvasuhte, lisa külgsuunas piirded)

Kokkuvõtte tabel ja tulemused pildi suurendamisest

küsimuse uri parameeter
väljaande pildi suurus

?resize=400×200
200×200

?resize=400×200^
400×400

?resize=400×200!
400×200 (mitte-proportsionaalselt)

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

Piltide staatiline suuruse muutmine Nginx-i ja LuaJIT (OpenResty) abil

Kokkuvõte

Kuna kogu selle lähenemise võimsuse ja lihtsuse tõttu on võimalik teostada asju, millel on üsna keeruline loogika, näiteks lisada veek Marke või rakendada autoriseerimist piiratud juurdepääsuga. API-võimaluste kohta piltide töötlemiseks saab tutvuda raamatukogu dokumentatsiooniga. isage/lua-imagick

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster