È passato un po' di tempo da quando, ispirato da un articolo è stato configurato il ridimensionamento delle immagini tramite e tutto funzionava come previsto. Ma è sorto un problema quando al manager è servito ricevere immagini con dimensioni esatte per il caricamento su alcuni servizi, poiché erano i loro requisiti tecnici. Ad esempio, se abbiamo un'immagine originale di dimensioni 1200×1200, e durante il ridimensionamento scriviamo qualcosa come ?resize=600×400, otterremo un'immagine proporzionalmente ridotta dal lato più corto, di dimensioni 400×400. Non è possibile ottenere un'immagine con una risoluzione maggiore (upscale). Cioè, ?resize=1500×1500 restituirà la stessa immagine 1200×1200
Un articolo è stato d'aiuto per comprendere come funziona Nginx con Lua e la libreria stessa per Lua — binding pure-c di Lua per ImageMagick. Perché è stata scelta questa soluzione invece di, diciamo, qualcosa in python — perché è veloce e comodo. Non dovrete nemmeno creare file, il tutto direttamente nella configurazione di Nginx (non obbligatorio).
Quindi, cosa ci serve
Gli esempi saranno basati su Debian.
Installazione di nginx e nginx-extras
apt-get update
apt-get install nginx-extrasInstallazione di LuaJIT
apt-get -y install lua5.1 luajit-5.1 libluajit-5.1-devInstallazione di imagemagick
apt-get -y install imagemagicke della libreria magickwand ad esso, nel mio caso per la versione 6
apt-cache search libmagickwand
apt-get -y install libmagickwand-6.q16-3 libmagickwand-6.q16-devCompilazione di lua-imagick
Cloniamo il repository (o scarichiamo lo zip e lo estraiamo)
cd ~
git clone https://github.com/isage/lua-imagick.git
cd lua-imagick
mkdir build
cd build
cmake ..
make
make installSe tutto è andato a buon fine, possiamo configurare Nginx.
Riporterò un esempio di configurazione del backend host, che si occupa effettivamente del ridimensionamento. Viene proxyato dal server front, anch'esso con Nginx, sul quale si esegue la cache per un certo tempo (un giorno) e altre cose.
configurazione backend 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
}
}
Ciò che era necessario (espansione dell'immagine ai bordi) avviene tramite img:extent() ed è definito tramite il parametro resize con il segno + alla fine.
I seguenti parametri sono disponibili:
- WxH (Mantieni il rapporto, usa la dimensione maggiore)
- WxH^ (Mantieni il rapporto, usa la dimensione minore (ritaglia))
- WxH! (Ignora il rapporto)
- WxH+ (Mantieni il rapporto, aggiungi bordi laterali)
Tabella riassuntiva dei risultati del ridimensionamento
Parametro uri della richiesta
Dimensione dell'immagine di output
?resize=400×200
200×200
?resize=400×200^
400×400
?resize=400×200!
400×200 (Non proporzionale)
?resize=400×200+
400×200 (Proporzionale)

Risultato
Considerando tutta la potenza e la semplicità di questo approccio, è possibile realizzare cose con logiche piuttosto complesse, come ad esempio aggiungere watermark o implementare l'autenticazione con accesso differenziato. Per scoprire le possibilità dell'API per lavorare con le immagini, è possibile fare riferimento alla documentazione della libreria
Fonte: habr.com
