Já há algum tempo, inspirado no artigo Redimensionando Imagens em Tempo Real , o redimensionamento de imagem com ngx_http_image_filter_module foi configurado e tudo funcionou como deveria. Mas havia um problema quando o gerente precisava obter imagens com tamanhos exatos para fazer o upload para alguns serviços, porque esses eram seus requisitos técnicos. Por exemplo, se tivermos uma imagem original do tamanho 1200x1200 e, ao redimensionar, escrevermos algo como ? Resize = 600x400 , obteremos uma imagem proporcionalmente reduzida na borda menor, tamanho 400x400 . Também é impossível obter uma imagem com uma resolução mais alta (upscale). Essa. ? redimensionar = 1500x1500 retornará a mesma imagem1200x1200
Um artigo do OpenResty veio ao resgate: transformamos o NGINX em um servidor de aplicativos completo para entender como o Nginx funciona com Lua e a biblioteca do próprio Lua isage / lua-imagick - ligações Lua pure-c ao ImageMagick. Por que essa solução foi escolhida, e não, digamos, algo em python - porque é rápida e conveniente. Você nem precisa criar arquivos, tudo está certo na configuração do Nginx (opcional).
Então, o que precisamos
Exemplos serão dados com base no Debian.
apt-get update
apt-get install nginx-extras
Instale LuaJIT
apt-get -y install lua5.1 luajit-5.1 libluajit-5.1-dev
Instale o imagemagick
apt-get -y install imagemagick
e as bibliotecas de varinha mágica , no meu caso para a versão 6
apt-cache search libmagickwand
apt-get -y install libmagickwand-6.q16-3 libmagickwand-6.q16-dev
Construção Lua-imagick
Clonamos o repositório (ou pegamos o zip e descompactamos)
cd ~
git clone https://github.com/isage/lua-imagick.git
cd lua-imagick
mkdir build
cd build
cmake ..
make
make install
Se tudo correu bem, você pode configurar o 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 o poder e a simplicidade dessa abordagem, você pode implementar coisas com uma lógica bastante complexa, por exemplo, adicionar marca d'água'i ou implementar autorização com acesso limitado. Para descobrir os recursos da API para trabalhar com imagens, você pode consultar a documentação da biblioteca isage / lua-imagick