Desde hace bastante tiempo, inspirado en el artículo Cambiar el tamaño de las imágenes sobre la marcha, se configuró el cambio de tamaño de la imagen con ngx_http_image_filter_module y todo funcionó como debería. Pero hubo un problema cuando el administrador necesitaba obtener imágenes con tamaños exactos para cargarlas en algunos servicios, porque Estos eran sus requisitos técnicos. Por ejemplo, si tenemos una imagen original de tamaño 1200x1200 , y al cambiar el tamaño escribimos algo como ? Cambiar tamaño = 600x400 , obtendremos una imagen reducida proporcionalmente en el borde más pequeño, tamaño 400x400 . También es imposible obtener una imagen con una resolución más alta (escala superior). Aquellos. ? resize = 1500x1500 devolverá la misma imagen1200x1200
Un artículo de OpenResty vino al rescate: convertimos NGINX en un servidor de aplicaciones completo para comprender cómo funciona Nginx con Lua y la biblioteca para Lua isage / lua-imagick en sí misma : enlaces de Lua pure-c a ImageMagick. Por qué se eligió esa solución, y no, digamos, algo en Python, porque es rápida y conveniente. Ni siquiera necesita crear ningún archivo, todo está en la configuración de Nginx (opcional).
Entonces, qué necesitamos
Se darán ejemplos basados en Debian.
apt-get update
apt-get install nginx-extras
Instalar LuaJIT
apt-get -y install lua5.1 luajit-5.1 libluajit-5.1-dev
Instalar imagemagick
apt-get -y install imagemagick
y las bibliotecas magickwand , en mi caso para la versión 6
apt-cache search libmagickwand
apt-get -y install libmagickwand-6.q16-3 libmagickwand-6.q16-dev
Lua-imagick build
Clonamos el repositorio (bueno, o tomamos el zip y lo desempaquetamos)
cd ~
git clone https://github.com/isage/lua-imagick.git
cd lua-imagick
mkdir build
cd build
cmake ..
make
make install
Si todo salió bien, puede configurar 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)

Dado el poder y la simplicidad de este enfoque, puede implementar cosas con una lógica bastante complicada, por ejemplo, agregar watermark'i o implementar autorización con acceso limitado. Para conocer las capacidades de la API para trabajar con imágenes, puede consultar la documentación de la biblioteca isage / lua-imagick