Už nějakou dobu, inspirováni článkem bylo nastavováno měření obrázků pomocí a všechno fungovalo jak má. Ale objevil se jeden problém, když manager potřeboval získat obrázky s přesnými rozměry pro nahrání na některé služby, protože to byly jejich technické požadavky. Například, pokud máme originál obrázku velikosti 1200×1200, a při měření píšeme něco jako ?resize=600×400, tak dostaneme proporcionálně zmenšený obrazec podle nejmenšího okraje, velikosti 400×400. Také není možné získat obrázek s vyšším rozlišením (upscale). T.j. ?resize=1500×1500 vrátí stále stejný obrázek 1200×1200
Na pomoc přišla článek pro pochopení, jak funguje Nginx s Lua a samotná knihovna pro Lua — Lua pure-c bindings to ImageMagick. Proč bylo vybráno takové řešení, a ne, dejme tomu, něco na python — protože je to rychlé a pohodlné. Nebudete muset vytvářet žádné soubory, vše přímo v konfigu Nginx (není povinné).
Takže, co budeme potřebovat
Příklady budou uvedeny na základě Debianu.
Instalace nginx a nginx-extras
apt-get update
apt-get install nginx-extrasInstalace LuaJIT
apt-get -y install lua5.1 luajit-5.1 libluajit-5.1-devInstalace imagemagick
apt-get -y install imagemagicka knihovny magickwand k němu, v mém případě pro 6. verzi
apt-cache search libmagickwand
apt-get -y install libmagickwand-6.q16-3 libmagickwand-6.q16-devSestavení lua-imagick
Naklonujeme repozitář (nebo vezmeme zip a rozbalíme)
cd ~
git clone https://github.com/isage/lua-imagick.git
cd lua-imagick
mkdir build
cd build
cmake ..
make
make installPokud vše proběhlo úspěšně, můžeme konfigurovat Nginx.
Uvedu příklad konfigu backend hosta, který se věnuje měření. Ten je procházen frontend serverem také s Nginx, na kterém dochází k ukládání do cache na určitou dobu (24 hodin) a podobným věcem.
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
}
}
To, co bylo požadováno (rozšíření obrázku po okrajích) se děje pomocí img:extent() a určuje se pomocí parametru resize se znaménkem + na konci.
Jsou dostupné následující parametry:
- WxH (Zachovat poměr stran, použít vyšší rozměr)
- WxH^ (Zachovat poměr stran, použít nižší rozměr (oříznout))
- WxH! (Ignorovat poměr stran)
- WxH+ (Zachovat poměr stran, přidat boční okraje)
Souhrnná tabulka s výsledky měření
Parametr uri požadavku
Velikost výstupního obrázku
?resize=400×200
200×200
?resize=400×200^
400×400
?resize=400×200!
400×200 (Neproporcionálně)
?resize=400×200+
400×200 (Proporcionálně)

Výsledek
Při zohlednění veškeré síly a jednoduchosti tohoto přístupu lze realizovat věci se poměrně složitou logikou, například přidávat watermarky nebo realizovat autorizaci s omezeným přístupem. Chcete-li zjistit možnosti API pro práci s obrázky, můžete se obrátit na dokumentaci knihovny.
Zdroj: habr.com
