Al geruime tijd, geïnspireerd door een artikel was er een configuratie voor het wijzigen van de grootte van afbeeldingen met behulp van en alles werkte zoals het hoorde. Maar er ontstond een probleem toen de manager afbeeldingen met exacte afmetingen nodig had voor upload naar bepaalde services, omdat dat hun technische vereisten waren. Bijvoorbeeld, als we een origineel van een afbeelding hebben met een grootte van 1200×1200, en bij het wijzigen van de grootte schrijven we iets als ?resize=600×400, dan krijgen we een proportioneel verkleinde afbeelding langs de kleinste rand, met een grootte van 400×400. Het is ook onmogelijk om een afbeelding met een hogere resolutie te verkrijgen (upscale). Dat wil zeggen, ?resize=1500×1500 zal dezelfde afbeelding retourneren 1200×1200
Een artikel kwam te hulp om te begrijpen hoe Nginx met Lua werkt en de bibliotheek voor Lua — Lua pure-c bindings naar ImageMagick. Waarom is deze oplossing gekozen en niet bijvoorbeeld iets in Python — omdat het snel en handig is. Je hoeft zelfs geen bestanden aan te maken, alles kan rechtstreeks in de Nginx-configuratie (niet verplicht).
Dus, wat hebben we nodig
Voorbeelden worden gegeven op basis van Debian.
Installatie van nginx en nginx-extras
apt-get update
apt-get install nginx-extrasInstallatie van LuaJIT
apt-get -y install lua5.1 luajit-5.1 libluajit-5.1-devInstallatie van imagemagick
apt-get -y install imagemagicken bibliotheek magickwand voor, in mijn geval voor versie 6
apt-cache search libmagickwand
apt-get -y install libmagickwand-6.q16-3 libmagickwand-6.q16-devBouwen van lua-imagick
Clone de repository (of haal de zip op en pak uit)
cd ~
git clone https://github.com/isage/lua-imagick.git
cd lua-imagick
mkdir build
cd build
cmake ..
make
make installAls alles succesvol is verlopen, kan Nginx worden geconfigureerd.
Ik geef een voorbeeld van de config van de backend host, die zich bezighoudt met het wijzigen van de grootte. Deze wordt geproxied door de frontendserver met Nginx, waarop caching plaatsvindt voor een bepaalde tijd (een dag) en andere zaken.
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
}
}
Wat nodig was (uitbreiding van de afbeelding aan de randen) gebeurt met behulp van img:extent() en wordt bepaald door de parameter resize met een teken + aan het einde.
De volgende parameters zijn beschikbaar:
- WxH (Behoud de aspectverhouding, gebruik de grotere dimensie)
- WxH^ (Behoud de aspectverhouding, gebruik de kleinere dimensie (crop))
- WxH! (Negeer de aspectverhouding)
- WxH+ (Behoud de aspectverhouding, voeg zijkanten toe)
Een samenvattende tabel met de resultaten van het wijzigen van de grootte
De uri parameter van de aanvraag
De grootte van de uitvoerafbeelding
?resize=400×200
200×200
?resize=400×200^
400×400
?resize=400×200!
400×200 (Niet proportioneel)
?resize=400×200+
400×200 (Proportioneel)

Conclusie
Gezien de kracht en eenvoud van deze aanpak, kunnen dingen met behoorlijk complexe logica worden geïmplementeerd, zoals het toevoegen van watermerken of het realiseren van autorisatie met beperkte toegang. Om de mogelijkheden van de API voor het werken met afbeeldingen te ontdekken, kan men de documentatie van de bibliotheek raadplegen.
Bron: habr.com
