Նա աստիճանաբար, ոգեշնչված լինելով հոդվածից կարգավորվեց պատկերների չափերի փոփոխությունը եւ ամեն ինչ գործում էր ինչպես պետք է։ Սակայն մեկ խնդիր առաջացավ, երբ մենեջերին անհրաժեշտ դարձավ ստանալ պատկերներ ճշգրիտ չափերով որոշ սպասարկման համար, քանի որ դրանք տեխնիկական պահանջներ էին։ Օրինակ, եթե մենք ունենք սկզբնական պատկեր, որի չափսը 1200×1200, եւ չափերի փոփոխության ընթացքում մենք գրում ենք ինչ-որ բան նման ?resize=600×400, ապա կունենանք համաչափ փոքրացված պատկերը ամենափոքրը կողմից, որի չափսը 400×400։ Այնպես էլ անհնար է ստանալ պատկերը ավելի բարձր լուծաչափով (upscale)։ Այսինքն, ?resize=1500×1500 կվերադարձնի նույն պատկերը 1200×1200
Օգնության եկավ հոդվածը նկարի փոփոխման գործընթացում Nginx-ի եւ Lua-ի գործիքների մասին, ինչպես նաեւ Lua-ի հաշվեկշռային գրադարանը — Lua-ի մաքուր կապերը ImageMagick-ի հետ: Ինչո՞ւ այս լուծումը, այլ ոչ թե, ասենք, ինչ-որ բան Python-ում — որովհետեւ սա արագ եւ հարմար է։ Ձեզ նույնիսկ չի անհրաժեշտ ստեղծել որեւէ ֆայլեր, ամեն ինչ ուղիղ Nginx-ի կոնֆիգում (ոչ պարտադիր)։
Ուրեմն, ինչն է մեզ անհրաժեշտ
Օրինակներ կտրվեն Debian-ի հիման վրա։
Նկարագիրն nginx եւ nginx-extras
apt-get update
apt-get install nginx-extrasՆկարագիր LuaJIT-ի համար
apt-get -y install lua5.1 luajit-5.1 libluajit-5.1-devՆկարագիր imagemagick-ի համար
apt-get -y install imagemagickեւ գրադարաններ magickwand իր հետ, իմ դեպքում 6-րդ տարբերակի համար
apt-cache search libmagickwand
apt-get -y install libmagickwand-6.q16-3 libmagickwand-6.q16-devlua-imagick-ի կառուցում
Քլոնավորում ենք ռեպոզիտարը (կամ վերցնում սեղմված ֆայլ եւ բացում)
cd ~
git clone https://github.com/isage/lua-imagick.git
cd lua-imagick
mkdir build
cd build
cmake ..
make
make installԵթե ամեն ինչ հաջողվեց, կարելի է կարգավորել Nginx-ը։
Կբերեմ օրինակ բեկեդի հոսթի կոնֆիգի, որը, իսկապես, զբաղվում է չափերի փոփոխությամբ։ Այն պրոքսի դրվում է դիմային սերվերի կողմից, նույնպես Nginx-ով, որտեղ կատարվում է կեշավորում որոշ ժամանակահատվածով (մեկ օր) եւ այլն։
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
}
}
Անկասկած պահանջվողինը (պատկերների մեծացում եզրալիզանում) տեղի է ունենում img:extent() եւ որոշվում է resize ն նշությամբ + ավարտին։
Հասանելի են հետեւյալ պարամետրերը։
- WxH (Պահպանել համաչափությունը, օգտագործել ավելի մեծ չափը)
- WxH^ (Պահպանել համաչափությունը, օգտագործել ավելի փոքր չափ (կրոպ))
- WxH! (Ignored aspect-ratio)
- WxH+ (Պահպանել համաչափությունը, ավելացնել կողմային սահմաններ)
Խմբագրված աղյուսակ՝ շրջանառությամբ
uri-request-ի պարամետր
Ելքային պատկերի չափը
?resize=400×200
200×200
?resize=400×200^
400×400
?resize=400×200!
400×200 (Ոչ համաչափ)
?resize=400×200+
400×200 (Համաչափ)

Եզրակացություն
Երկարության եւ պարզության ողջ ուժով այս մոտեցումը կարող է իրականացնել բավականին բարդ տրամաբանություն, օրինակ՝ ջրվեժներ ավելացնել կամ իրականացնել արգելափակում սահմաններից։ API-ի հնարավորությունները պատկերների հետ աշխատելու համար կարող եք դիմել գրադարանի փաստաթղթին
Ընտանիք: habr.com
