För ganska länge sedan, inspirerad av en artikel var bildstorleken konfigurerad med hjälp av och allt fungerade som det skulle. Men ett problem uppstod när en chef behövde få bilder med exakta mått för uppladdning till vissa tjänster, eftersom det var deras tekniska krav. Till exempel, om vi har en originalbild som är 1200×1200och när vi gör en resize skriver vi något i stil med ?resize=600×400, får vi en proportionellt minskad bild på den minsta kanten, med måttet 400×400. Det är också omöjligt att få en bild med högre upplösning (upscale). Det vill säga, ?resize=1500×1500 kommer att returnera samma bild 1200×1200
En artikel kom till hjälp för att förstå hur Nginx fungerar med Lua och själva biblioteket för Lua — Lua pure-c-bindningar till ImageMagick. Varför detta valdes istället för något på python, till exempel, är för att det är snabbt och bekvämt. Du behöver inte ens skapa några filer, allt görs direkt i Nginx-konfigurationen (inte nödvändigt).
Så, vad behöver vi
Exempel kommer att ges baserat på Debian.
Installera nginx och nginx-extras
apt-get update
apt-get install nginx-extrasInstallera LuaJIT
apt-get -y install lua5.1 luajit-5.1 libluajit-5.1-devInstallera imagemagick
apt-get -y install imagemagickoch biblioteken magickwand till den, i mitt fall för version 6
apt-cache search libmagickwand
apt-get -y install libmagickwand-6.q16-3 libmagickwand-6.q16-devBygga lua-imagick
Klona repot (eller hämta zip och packa upp det)
cd ~
git clone https://github.com/isage/lua-imagick.git
cd lua-imagick
mkdir build
cd build
cmake ..
make
make installOm allt har gått bra kan du konfigurera Nginx.
Jag ger ett exempel på konfigurationen av backend-värden, som faktiskt hanterar resizing. Den proxas av frontend-servern också med Nginx, där caching sker under en viss tid (24 timmar) och så vidare.
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
}
}
Det som behövdes (utvidgning av bilden på kanterna) sker med hjälp av img:extent() och definieras med parametern resize med ett tecken + i slutet.
Följande parametrar är tillgängliga:
- WxH (Behåll aspektkvot, använd högre dimension)
- WxH^ (Behåll aspektkvot, använd lägre dimension (beskär))
- WxH! (Ignorera aspektkvot)
- WxH+ (Behåll aspektkvot, lägg till sidokanter)
Sammanfattningstabell med resultaten av resizing
Parameter uri i förfrågan
Utgångsbildens storlek
?resize=400×200
200×200
?resize=400×200^
400×400
?resize=400×200!
400×200 (Icke-proportionellt)
?resize=400×200+
400×200 (Proportionellt)

Resultat
Med all kraft och enkelhet i en sådan metod går det att realisera saker med ganska komplex logik, till exempel att lägga till vattenstämplar eller implementera autentisering med begränsad åtkomst. För att ta reda på API-möjligheterna för att arbeta med bilder kan man hänvisa till dokumentationen för biblioteket.
Källa: habr.com
