For længe siden, inspireret af en artikel blev der konfigureret resizing af billeder ved hjælp af og det fungerede som det skulle. Men der opstod et problem, da en medarbejder havde brug for at hente billeder med præcise dimensioner til upload til visse tjenester, da det var deres tekniske krav. For eksempel, hvis vi har det originale billede i størrelsen 1200×1200, og når vi resize, skriver vi noget i retning af ?resize=600×400, så får vi et proportionalt reduceret billede langs den mindste kant, som måler 400×400. Det er heller ikke muligt at få et billede med en større opløsning (upscale). Det vil sige, ?resize=1500×1500 vil returnere det samme billede 1200×1200
En artikel hjalp mig med at forstå, hvordan Nginx fungerer med Lua og selve biblioteket til Lua — Lua pure-c bindings til ImageMagick. Hvorfor blev denne løsning valgt frem for noget på Python - fordi det er hurtigt og bekvemt. Du behøver endda ikke at oprette nogen filer, alt er direkte i Nginx-konfigurationen (hvilket ikke er nødvendigt).
Så hvad har vi brug for
Eksemplerne vil blive givet på Debian.
Installation af nginx og nginx-extras
apt-get update
apt-get install nginx-extrasInstallation af LuaJIT
apt-get -y install lua5.1 luajit-5.1 libluajit-5.1-devInstallation af imagemagick
apt-get -y install imagemagickog biblioteket magickwand til det, i mit tilfælde for version 6
apt-cache search libmagickwand
apt-get -y install libmagickwand-6.q16-3 libmagickwand-6.q16-devBygning af lua-imagick
Klone depotet (eller hente zip og udpakke det)
cd ~
git clone https://github.com/isage/lua-imagick.git
cd lua-imagick
mkdir build
cd build
cmake ..
make
make installHvis alt gik vel, kan du konfigurere Nginx.
Jeg vil give et eksempel på konfigurationen af backend-host, som netop beskæftiger sig med resizing. Den proxyes af frontend-serveren også med Nginx, hvor caching finder sted i et stykke tid (24 timer) og andre ting.
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, der var nødvendigt (udvidelse af billedet langs kanterne), sker med hjælp af img:extent() og bestemmes ved hjælp af parameteren resize med tegn + i slutningen.
De følgende parametre er tilgængelige:
- WxH (Behold aspektforhold, brug højere dimension)
- WxH^ (Behold aspektforhold, brug lavere dimension (beskær))
- WxH! (Ignorer aspektforhold)
- WxH+ (Behold aspektforhold, tilføj sidekanter)
Oversigtstabel med resultaterne af resizing
Parameteren uri i forespørgslen
Størrelsen på det udgående billede
?resize=400×200
200×200
?resize=400×200^
400×400
?resize=400×200!
400×200 (Ikke proportionalt)
?resize=400×200+
400×200 (Proportionalt)

Resultat
Med al den kraft og enkelhed, som denne tilgang tilbyder, kan man implementere ret komplekse logikker, såsom at tilføje vandmærker eller realisere godkendelse med begrænset adgang. For at finde ud af API'ets muligheder for billedbehandling kan man konsultere dokumentationen for biblioteket.
Kilde: habr.com
