Depuis un certain temps maintenant, inspiré par l'article Redimensionner les images à la volée , le redimensionnement d'image avec ngx_http_image_filter_module a été configuré et tout a fonctionné comme il se doit. Mais il y avait un problème lorsque le gestionnaire devait obtenir des images de tailles exactes pour les télécharger sur certains services, car c'étaient leurs exigences techniques. Par exemple, si nous avons une image originale de taille 1200x1200 , et lors du redimensionnement, nous écrivons quelque chose comme ? Resize = 600x400 , nous obtiendrons une image proportionnellement réduite au plus petit bord, taille 400x400 . Il est également impossible d'obtenir une image avec une résolution plus élevée (haut de gamme). Ceux. ? resize = 1500x1500 renverra tout de même la même image1200x1200
Un article d' OpenResty est venu à la rescousse: nous transformons NGINX en un serveur d'applications à part entière pour comprendre comment Nginx fonctionne avec Lua et la bibliothèque pour Lua isage / lua-imagick elle-même - Lia pure-c bindings à ImageMagick. Pourquoi une telle solution a été choisie, et non, disons, quelque chose en python - parce qu'elle est rapide et pratique. Vous n'avez même pas besoin de créer de fichiers, tout se passe bien dans la configuration Nginx (facultatif).
Alors de quoi avons-nous besoin
Des exemples seront donnés sur la base de Debian.
apt-get update
apt-get install nginx-extras
Installer LuaJIT
apt-get -y install lua5.1 luajit-5.1 libluajit-5.1-dev
Installer imagemagick
apt-get -y install imagemagick
et les bibliothèques magickwand , dans mon cas pour la version 6
apt-cache search libmagickwand
apt-get -y install libmagickwand-6.q16-3 libmagickwand-6.q16-dev
Construction Lua-imagick
Nous clonons le référentiel (enfin, ou prenons le zip et le déballons)
cd ~
git clone https://github.com/isage/lua-imagick.git
cd lua-imagick
mkdir build
cd build
cmake ..
make
make install
Si tout s'est bien passé, vous pouvez configurer Nginx.
backend , , , . Nginx, () . .
nginx backend config
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;
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;
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 imageserver {
server localhost:8082;
}
server {
listen 80;
server_name examaple.lh;
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;
}
}
, ( ) img:extent()
resize
+
.
:
- WxH (Keep aspect-ratio, use higher dimension)
- WxH^ (Keep aspect-ratio, use lower dimension (crop))
- WxH! (Ignore aspect-ratio)
- WxH+ (Keep aspect-ratio, add side borders)

Étant donné la puissance et la simplicité de cette approche, vous pouvez implémenter des choses avec une logique plutôt complexe, par exemple, ajouter watermark'i ou implémenter une autorisation avec un accès limité. Afin de découvrir les capacités de l'API pour travailler avec des images, vous pouvez vous référer à la documentation de la bibliothèque isage / lua-imagick