Es ist schon eine Weile her, dass ich von einem Artikel inspiriert wurde das Resizing von Bildern mithilfe von und alles funktionierte wie es sollte. Doch es gab ein Problem, als der Manager Bilder mit genauen Abmessungen benötigte, um sie auf bestimmten Diensten hochzuladen, da dies ihre technischen Anforderungen waren. Zum Beispiel, wenn wir ein Originalbild mit der Größe haben 1200×1200, und beim Resizing wir etwas wie ?resize=600×400angeben, erhalten wir ein proportional verkleinertes Bild an der kleinsten Kante mit der Größe von 400×400. Es ist auch unmöglich, ein Bild mit höherer Auflösung zu erhalten (Upscale). Das heißt, ?resize=1500×1500 wird das gleiche Bild zurückgeben 1200×1200
Ein Artikel kam zur Rettung um zu verstehen, wie Nginx mit Lua arbeitet und die Bibliothek selbst für Lua — Lua Pure-C-Bindings zu ImageMagick. Warum wurde diese Lösung gewählt und nicht zum Beispiel etwas in Python? Weil es schnell und bequem ist. Sie müssen nicht einmal irgendwelche Dateien erstellen, alles erfolgt direkt in der Nginx-Konfiguration (nicht zwingend).
Also, was brauchen wir
Die Beispiele werden auf Grundlage von Debian gegeben.
Installation von nginx und nginx-extras
apt-get update
apt-get install nginx-extrasInstallation von LuaJIT
apt-get -y install lua5.1 luajit-5.1 libluajit-5.1-devInstallation von imagemagick
apt-get -y install imagemagickund der Bibliothek magickwand dazu, in meinem Fall für Version 6
apt-cache search libmagickwand
apt-get -y install libmagickwand-6.q16-3 libmagickwand-6.q16-devKomplilierung von lua-imagick
Wir klonen das Repository (oder holen das Zip und entpacken es)
cd ~
git clone https://github.com/isage/lua-imagick.git
cd lua-imagick
mkdir build
cd build
cmake ..
make
make installWenn alles erfolgreich war, können wir Nginx konfigurieren.
Ich werde ein Beispiel für die Konfiguration des Backend-Hosts anführen, der das Resizing tatsächlich vornimmt. Er wird ebenfalls von einem Front-Server mit Nginx weitergeleitet, wo eine Cachebildung für eine gewisse Zeit (24 Stunden) usw. stattfindet.
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
}
}
Das, was benötigt wurde (Erweiterung des Bildes an den Rändern), erfolgt durch img:extent() und wird durch den Parameter resize mit dem Zeichen + am Ende bestimmt.
Folgende Parameter sind verfügbar:
- WxH (Seitenverhältnis beibehalten, größere Dimension verwenden)
- WxH^ (Seitenverhältnis beibehalten, kleinere Dimension verwenden (croppen))
- WxH! (Seitenverhältnis ignorieren)
- WxH+ (Seitenverhältnis beibehalten, seitliche Ränder hinzufügen)
Zusammenfassungstabelle mit den Ergebnissen des Resizings
Parameter der URI-Anfrage
Größe des Ausgangsbildes
?resize=400×200
200×200
?resize=400×200^
400×400
?resize=400×200!
400×200 (Nicht proportional)
?resize=400×200+
400×200 (Proportional)

Fazit
Angesichts der gesamten Kraft und Einfachheit eines solchen Ansatzes lassen sich relativ komplexe Logik implementieren, zum Beispiel Wasserzeichen hinzufügen oder eine Authentifizierung mit eingeschränktem Zugriff realisieren. Um die Möglichkeiten der API zur Bildbearbeitung zu erkunden, kann man die Dokumentation der Bibliothek konsultieren.
Quelle: habr.com
