Ndryshimi i madhësisë së imazheve në fluturim duke përdorur Nginx dhe LuaJIT (OpenResty)

Prej shumë kohësh, frymëzuar nga artikulli Ndryshimi i madhësisë së imazheve në fluturim Ndryshimi i madhësisë së imazhit u konfigurua duke përdorur ngx_http_image_filter_module dhe gjithçka funksionoi ashtu siç duhej. Por një problem lindi kur menaxheri duhej të merrte imazhe me dimensione të sakta për t'u ngarkuar në disa shërbime, sepse... këto ishin kërkesat e tyre teknike. Për shembull, nëse kemi një imazh origjinal të madhësisë 1200 × 1200, dhe kur ndryshojmë madhësinë shkruajmë diçka të tillë ?përmasa=600×400, atëherë marrim një imazh të reduktuar proporcionalisht përgjatë skajit, madhësisë më të vogël 400 × 400. Është gjithashtu e pamundur të marrësh një imazh me rezolucion më të lartë (të pasura). Ato. ?përmasa=1500×1500 do të kthejë të njëjtin imazh 1200 × 1200

Ky artikull erdhi në shpëtim OpenResty: duke e kthyer NGINX në një server aplikacioni të plotë për të kuptuar se si punon Nginx me Lua dhe vetë biblioteka për Luan isage/lua-imagick - Lidhjet e pastër-c për ImageMagick. Pse u zgjodh kjo zgjidhje, dhe jo, të themi, diçka në python - sepse është e shpejtë dhe e përshtatshme. Ju as nuk keni nevojë të krijoni ndonjë skedar, gjithçka është në rregull në konfigurimin Nginx (opsionale).

Pra, çfarë na duhet

Shembujt do të jepen bazuar në Debian.

Instalimi i nginx dhe nginx-ekstra

apt-get update
apt-get install nginx-extras

Duke instaluar LuaJIT

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

Instalimi i imagemagick

apt-get -y install imagemagick

dhe bibliotekat shkop magjik për të, në rastin tim për versionin 6

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

Ndërtimi lua-imagick

Ne klonojmë depon (ose marrim zip-in dhe shpaketojmë)

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

Nëse gjithçka shkoi mirë, mund të konfiguroni Nginx.

Unë do të jap një shembull të konfigurimit të hostit të backend, i cili, në fakt, është përgjegjës për ndryshimin e madhësisë. Proksohet nga serveri i përparmë, gjithashtu me Nginx, ku ndodh caching për një periudhë të caktuar kohe (ditë) dhe gjëra të tjera.

konfigurimi i nginx backend

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

Ajo që kërkohej (zgjerimi i imazhit rreth skajeve) ndodh duke përdorur img:extent() dhe përcaktohet duke përdorur parametrin resize me një shenjë + në fund.

Opsionet e mëposhtme janë në dispozicion:

  • WxH (Mbaje raportin e pamjes, përdor dimension më të lartë)
  • WxH^ (Mbaje raportin e pamjes, përdor dimensionin më të ulët (prerje))
  • WxH! (Injoro raportin e pamjes)
  • WxH+ (Mbaje raportin e pamjes, shto kufijtë anësore)

Tabela përmbledhëse me rezultatet e ndryshimit të madhësisë

Kërkoni parametrin uri
Madhësia e imazhit në dalje

?përmasa=400×200
200 × 200

?resize=400×200^
400 × 400

?resize=400×200!
400×200 (Jo proporcionale)

?përmasa=400×200+
400×200 (proporcionale)

Ndryshimi i madhësisë së imazheve në fluturim duke përdorur Nginx dhe LuaJIT (OpenResty)

Total

Duke marrë parasysh fuqinë dhe thjeshtësinë e kësaj qasjeje, ju mund të zbatoni gjëra me logjikë mjaft komplekse, për shembull, duke shtuar filigranë ose duke zbatuar autorizim me akses të kufizuar. Për të zbuluar aftësitë e API për të punuar me imazhe, mund t'i referoheni dokumentacionit të bibliotekës isage/lua-imagick

Burimi: www.habr.com

Shto një koment