Mainiet attēlu izmērus, izmantojot Nginx un LuaJIT (OpenResty)

Jau labu laiku, iedvesmojoties no raksta Mainiet attēlu izmērus uzreiz attēla izmēra maiņa tika konfigurēta, izmantojot ngx_http_image_filter_module un viss strādāja kā nākas. Taču viena problēma radās, kad pārvaldniekam vajadzēja saņemt attēlus ar precīziem izmēriem, lai tos augšupielādētu dažos servisos, jo... tās bija viņu tehniskās prasības. Piemēram, ja mums ir oriģināls izmēra attēls 1200 × 1200, un mainot izmēru mēs rakstām kaut ko līdzīgu ?resize=600×400, tad iegūstam proporcionāli samazinātu attēlu gar mazāko malu, izmēru 400 × 400. Tāpat nav iespējams iegūt attēlu ar augstāku izšķirtspēju (upscale). Tie. ?resize=1500×1500 atgriezīs to pašu attēlu 1200 × 1200

Šis raksts nāca palīgā OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri lai saprastu, kā Nginx strādā ar Lua un pašu Lua bibliotēku isage/lua-imagick - Lua pure-c stiprinājumi ImageMagick. Kāpēc tika izvēlēts šis risinājums, nevis, teiksim, kaut kas python - jo tas ir ātri un ērti. Jums pat nav jāizveido faili, viss ir pareizi Nginx konfigurācijā (pēc izvēles).

Tātad, kas mums vajadzīgs

Piemēri tiks sniegti, pamatojoties uz Debian.

Nginx un nginx-extras instalēšana

apt-get update
apt-get install nginx-extras

LuaJIT instalēšana

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

Imagemagick instalēšana

apt-get -y install imagemagick

un bibliotēkas burvju nūjiņa uz to, manā gadījumā 6. versijai

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

Lua-imagick celtniecība

Mēs klonējam repozitoriju (vai paņemam rāvējslēdzēju un izpakojam to)

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

Ja viss noritēja labi, varat konfigurēt Nginx.

Es sniegšu piemēru aizmugursistēmas resursdatora konfigurācijai, kas patiesībā ir atbildīga par izmēru maiņu. To nodrošina priekšējais serveris, arī ar Nginx, kur notiek kešatmiņa uz noteiktu laiku (dienas) un citas lietas.

nginx aizmugursistēmas konfigurācija

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

Tas, kas bija nepieciešams (attēla paplašināšana ap malām), notiek, izmantojot img:extent() un tiek definēts, izmantojot parametru resize ar zīmi + beigās.

Ir pieejamas šādas opcijas:

  • WxH (saglabājiet malu attiecību, izmantojiet lielāku izmēru)
  • WxH^ (saglabājiet malu attiecību, izmantojiet zemāku izmēru (apgriezt))
  • PxH! (Ignorēt malu attiecību)
  • WxH+ (saglabājiet malu attiecību, pievienojiet sānu apmales)

Kopsavilkuma tabula ar izmēru maiņas rezultātiem

Pieprasīt uri parametru
Izvades attēla izmērs

?resize=400×200
200 × 200

?resize=400×200^
400 × 400

?resize=400×200!
400 × 200 (nav proporcionāls)

?resize=400×200+
400 × 200 (proporcionāli)

Mainiet attēlu izmērus, izmantojot Nginx un LuaJIT (OpenResty)

Kopsavilkums

Ņemot vērā šīs pieejas jaudu un vienkāršību, jūs varat īstenot lietas ar diezgan sarežģītu loģiku, piemēram, pievienot ūdenszīmes vai ieviest autorizāciju ar ierobežotu piekļuvi. Lai uzzinātu API iespējas darbam ar attēliem, varat skatīt bibliotēkas dokumentāciju isage/lua-imagick

Avots: www.habr.com

Pievieno komentāru