È passato un po' di tempo, ispirato da un articolo è stato configurato il ridimensionamento delle immagini utilizzando e tutto funzionava come previsto. Ma è emerso un problema, quando il manager ha avuto bisogno di ottenere immagini con dimensioni esatte per il caricamento su alcuni servizi, poiché erano i loro requisiti tecnici. Ad esempio, se abbiamo l'originale dell'immagine di dimensioni 1200×1200, e durante il ridimensionamento scriviamo qualcosa come ?resize=600×400, otterremo un'immagine ridimensionata proporzionalmente per il lato più corto, delle dimensioni 400×400. Inoltre, non è possibile ottenere un'immagine con una risoluzione maggiore (upscale). Cioè, ?resize=1500×1500 restituirà la stessa immagine 1200×1200
Un articolo è venuto in aiuto per comprendere come Nginx lavora con Lua e la stessa libreria per Lua — collegamenti pure-c di Lua a ImageMagick. Perché è stata scelta questa soluzione, piuttosto che, diciamo, qualcosa in python — perché è veloce e comoda. Non è necessario creare alcun file, tutto direttamente nella configurazione di Nginx (non obbligatorio).
Quindi, di cosa abbiamo bisogno
Gli esempi saranno forniti sulla base di 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-devInstallare imagemagick
apt-get -y install imagemagicke librerie 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-devCompilare lua-imagick
Cloniamo il repository (oppure scarichiamo il 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, si può configurare Nginx.
Ecco un esempio di configurazione del backend host, che si occupa effettivamente del ridimensionamento. Viene proxy passato dal server frontale sempre con Nginx, dove avviene anche la cache per un certo periodo (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 richiesto (espansione dell'immagine ai bordi) avviene tramite img:extent() ed è definito dal parametro resize con segno + alla fine.
I seguenti parametri sono disponibili:
- WxH (Mantieni il rapporto d'aspetto, usa la dimensione maggiore)
- WxH^ (Mantieni il rapporto d'aspetto, usa la dimensione minore (ritaglia))
- WxH! (Ignora il rapporto d'aspetto)
- WxH+ (Mantieni il rapporto d'aspetto, aggiungi bordi laterali)
Tabella riassuntiva con i risultati del ridimensionamento
Parametro uri della richiesta
Dimensione dell'immagine di uscita
?resize=400×200
200×200
?resize=400×200^
400×400
?resize=400×200!
400×200 (Non proporzionale)
?resize=400×200+
400×200 (Proporzionale)

Risultato
Data la potenza e la semplicità di questo approccio, è possibile realizzare operazioni con logiche piuttosto complesse, come aggiungere watermark o implementare l'autenticazione con accesso differenziato. Per scoprire le possibilità dell'API per la gestione delle immagini, è possibile consultare la documentazione della libreria.
Fonte: habr.com
