Badilisha ukubwa wa picha kwenye kuruka kwa kutumia Nginx na LuaJIT (OpenResty)

Kwa muda mrefu sasa, ikiongozwa na kifungu hicho Picha inabadilisha ukubwa kwenye nzi urekebishaji ukubwa wa picha uliwekwa kwa kutumia ngx_http_moduli_ya_kichujio na kila kitu kilifanya kazi kama inavyopaswa. Lakini shida moja ilitokea wakati meneja alihitaji kupokea picha zenye vipimo kamili vya kupakiwa kwa huduma zingine, kwa sababu ... haya yalikuwa mahitaji yao ya kiufundi. Kwa mfano, ikiwa tunayo picha ya asili ya ukubwa 1200 Γ— 1200, na wakati wa kubadilisha ukubwa tunaandika kitu kama ?resize=600Γ—400, basi tunapata picha iliyopunguzwa kwa uwiano kando ya makali madogo zaidi, ukubwa 400 Γ— 400. Pia haiwezekani kupata picha na azimio la juu (upscale). Wale. ?resize=1500Γ—1500 itarudisha picha sawa 1200 Γ— 1200

Nakala hii ilikuja kuwaokoa OpenResty: kugeuza NGINX kuwa seva ya programu kamili kuelewa jinsi Nginx inavyofanya kazi na Lua na maktaba yenyewe ya Lua isage/lua-imagick - Vifungo vya Lua pure-c kwa ImageMagick. Kwa nini suluhisho hili lilichaguliwa, na sio, sema, kitu katika python - kwa sababu ni haraka na rahisi. Hauitaji hata kuunda faili zozote, kila kitu kiko sawa kwenye usanidi wa Nginx (hiari).

Kwa hivyo tunahitaji nini

Mifano itatolewa kulingana na Debian.

Kufunga nginx na nginx-ziada

apt-get update
apt-get install nginx-extras

Inasakinisha LuaJIT

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

Inasakinisha imagemagick

apt-get -y install imagemagick

na maktaba magickwand kwake, kwa upande wangu kwa toleo la 6

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

Kujenga lua-imagick

Tunatengeneza hazina (au kuchukua zip na kuifungua)

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

Ikiwa kila kitu kilikwenda vizuri, unaweza kusanidi Nginx.

Nitatoa mfano wa usanidi wa mwenyeji wa nyuma, ambayo, kwa kweli, inawajibika kwa kurekebisha ukubwa. Imewekwa na seva ya mbele, pia na Nginx, ambapo caching hutokea kwa muda fulani (siku) na mambo mengine.

usanidi wa nyuma wa nginx

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

Kilichohitajika (kupanua picha karibu na kingo) hufanyika kwa kutumia img:extent() na hufafanuliwa kwa kutumia parameta resize na ishara + mwishoni.

Chaguzi zifuatazo zinapatikana:

  • WxH (Weka uwiano wa kipengele, tumia kipimo cha juu)
  • WxH^ (Weka uwiano wa kipengele, tumia kipimo cha chini (mazao))
  • WxH! (Puuza uwiano wa kipengele)
  • WxH+ (Weka uwiano wa kipengele, ongeza mipaka ya kando)

Jedwali la muhtasari na matokeo ya kubadilisha ukubwa

Omba kigezo cha uri
Ukubwa wa Picha ya Pato

?resize=400Γ—200
200 Γ— 200

?resize=400Γ—200^
400 Γ— 400

?resize=400Γ—200!
400Γ—200 (Si sawia)

?resize=400Γ—200+
400Γ—200 (Uwiano)

Badilisha ukubwa wa picha kwenye kuruka kwa kutumia Nginx na LuaJIT (OpenResty)

Jumla ya

Kuzingatia nguvu na unyenyekevu wa mbinu hii, unaweza kutekeleza mambo kwa mantiki ngumu kabisa, kwa mfano, kuongeza watermarks au kutekeleza idhini na upatikanaji mdogo. Ili kujua uwezo wa API wa kufanya kazi na picha, unaweza kurejelea nyaraka za maktaba isage/lua-imagick

Chanzo: mapenzi.com

Kuongeza maoni