Baguhin ang laki ng mga larawan sa mabilisang gamit ang Nginx at LuaJIT (OpenResty)

Sa loob ng ilang panahon ngayon, inspirasyon ng artikulo Baguhin ang laki ng mga imahe sa mabilisang Ang pagbabago ng laki ng imahe ay na-configure gamit ang ngx_http_image_filter_module at lahat ay gumana ayon sa nararapat. Ngunit isang problema ang lumitaw nang kailangan ng manager na makatanggap ng mga larawang may eksaktong sukat para sa pag-upload sa ilang mga serbisyo, dahil... ito ang kanilang mga teknikal na pangangailangan. Halimbawa, kung mayroon kaming orihinal na larawan ng laki 1200 Γ— 1200, at kapag nagre-resize kami nagsusulat kami ng tulad ng ?resize=600Γ—400, pagkatapos ay makakakuha tayo ng proporsyonal na pinababang imahe kasama ang pinakamaliit na gilid, laki 400 Γ— 400. Imposible ring makakuha ng imahe na may mas mataas na resolution (upscale). Yung. ?resize=1500Γ—1500 ibabalik ang parehong imahe 1200 Γ— 1200

Ang artikulong ito ay dumating upang iligtas OpenResty: ginagawang isang ganap na server ng application ang NGINX upang maunawaan kung paano gumagana ang Nginx kay Lua at sa mismong library para kay Lua isage/lua-imagick - Lua pure-c bindings sa ImageMagick. Bakit napili ang solusyon na ito, at hindi, sabihin, isang bagay sa python - dahil ito ay mabilis at maginhawa. Hindi mo na kailangang lumikha ng anumang mga file, ang lahat ay tama sa Nginx config (opsyonal).

Kaya kung ano ang kailangan namin

Ang mga halimbawa ay ibibigay batay sa Debian.

Pag-install ng nginx at nginx-extras

apt-get update
apt-get install nginx-extras

Pag-install ng LuaJIT

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

Pag-install ng imagemagick

apt-get -y install imagemagick

at mga aklatan magickwand dito, sa aking kaso para sa bersyon 6

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

Pagbuo ng lua-imagick

Kino-clone namin ang repositoryo (o kunin ang zip at i-unpack ito)

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

Kung naging maayos ang lahat, maaari mong i-configure ang Nginx.

Magbibigay ako ng isang halimbawa ng config ng backend host, na, sa katunayan, ay responsable para sa pagbabago ng laki. Ito ay na-proxy ng front server, kasama din ng Nginx, kung saan nagaganap ang pag-cache para sa isang tiyak na tagal ng panahon (mga araw) at iba pang mga bagay.

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

Ano ang kinakailangan (pagpapalawak ng imahe sa paligid ng mga gilid) ay nangyayari gamit img:extent() at tinukoy gamit ang parameter resize na may tanda + sa dulo.

Available ang mga sumusunod na opsyon:

  • WxH (Panatilihin ang aspect-ratio, gumamit ng mas mataas na dimensyon)
  • WxH^ (Panatilihin ang aspect-ratio, gumamit ng mas mababang dimensyon (crop))
  • WxH! (Balewalain ang aspect-ratio)
  • WxH+ (Panatilihin ang aspect-ratio, magdagdag ng mga gilid na hangganan)

Talahanayan ng buod na may mga resulta ng pagbabago ng laki

Humiling ng uri ng parameter
Laki ng Larawan ng Output

?resize=400Γ—200
200 Γ— 200

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

?resize=400Γ—200!
400Γ—200 (Hindi proporsyonal)

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

Baguhin ang laki ng mga larawan sa mabilisang gamit ang Nginx at LuaJIT (OpenResty)

Kabuuan

Isinasaalang-alang ang kapangyarihan at pagiging simple ng diskarteng ito, maaari mong ipatupad ang mga bagay na may medyo kumplikadong lohika, halimbawa, pagdaragdag ng mga watermark o pagpapatupad ng awtorisasyon na may limitadong pag-access. Upang malaman ang mga kakayahan ng API para sa pagtatrabaho sa mga larawan, maaari kang sumangguni sa dokumentasyon ng library isage/lua-imagick

Pinagmulan: www.habr.com

Magdagdag ng komento