Od dłuższego czasu inspirowany artykułem
Ten artykuł przyszedł na ratunek
Czego więc potrzebujemy
Przykłady zostaną podane w oparciu o Debiana.
Instalowanie nginx i dodatków nginx
apt-get update
apt-get install nginx-extras
Instalowanie LuaJIT
apt-get -y install lua5.1 luajit-5.1 libluajit-5.1-dev
Instalowanie imagemagicka
apt-get -y install imagemagick
i biblioteki magiczna różdżka do tego, w moim przypadku do wersji 6
apt-cache search libmagickwand
apt-get -y install libmagickwand-6.q16-3 libmagickwand-6.q16-dev
Budowanie lua-imagick
Klonujemy repozytorium (lub bierzemy zip i rozpakowujemy)
cd ~
git clone https://github.com/isage/lua-imagick.git
cd lua-imagick
mkdir build
cd build
cmake ..
make
make install
Jeśli wszystko poszło dobrze, możesz skonfigurować Nginx.
Podam przykład konfiguracji hosta backendowego, który tak naprawdę odpowiada za zmianę rozmiaru. Jest proxy przez serwer frontowy, również z Nginxem, gdzie buforowanie odbywa się przez określony czas (dni) i inne rzeczy.
konfiguracja zaplecza nginx
# 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
}
}
To, co było wymagane (rozszerzanie obrazu wokół krawędzi), dzieje się za pomocą img:extent()
i jest definiowany za pomocą parametru resize
podpisany +
na końcu.
Dostępne są następujące opcje:
- SxW (Zachowaj proporcje, użyj większego wymiaru)
- SxW^ (Zachowaj proporcje, użyj mniejszego wymiaru (przytnij))
- szer. x wys.! (Zignoruj proporcje)
- SxW+ (Zachowaj proporcje, dodaj boczne krawędzie)
Tabela podsumowująca z wynikami zmiany rozmiaru
Żądanie parametru uri
Rozmiar obrazu wyjściowego
?zmienić rozmiar=400×200
200 × 200
?zmienić rozmiar=400×200^
400 × 400
?zmienić rozmiar=400×200!
400×200 (nieproporcjonalne)
?zmienić rozmiar=400×200+
400×200 (proporcjonalne)
Łączny
Biorąc pod uwagę siłę i prostotę tego podejścia, możesz wdrażać rzeczy o dość złożonej logice, na przykład dodając znaki wodne lub wdrażając autoryzację z ograniczonym dostępem. Aby poznać możliwości API do pracy z obrazami, możesz zapoznać się z dokumentacją biblioteki
Źródło: www.habr.com