ΠΠ΅ΡΠ΅ ΠΏΠΎΠ΄ΠΎΠ»Π³ΠΎ Π²ΡΠ΅ΠΌΠ΅, ΠΈΠ½ΡΠΏΠΈΡΠΈΡΠ°Π½ ΠΎΠ΄ ΡΡΠ°ΡΠΈΡΠ°ΡΠ°
ΠΠ²ΠΎΡ Π½Π°ΠΏΠΈΡ Π΄ΠΎΡΠ΄Π΅ Π½Π° ΠΏΠΎΠΌΠΎΡ
ΠΠ° ΡΡΠΎ Π½ΠΈ ΡΡΠ΅Π±Π°
ΠΠ΅ Π±ΠΈΠ΄Π°Ρ Π΄Π°Π΄Π΅Π½ΠΈ ΠΏΡΠΈΠΌΠ΅ΡΠΈ Π²ΡΠ· ΠΎΡΠ½ΠΎΠ²Π° Π½Π° Debian.
ΠΠ½ΡΡΠ°Π»ΠΈΡΠ°ΡΠ΅ nginx ΠΈ nginx-Π΅ΠΊΡΡΡΠ°ΡΠΈ
apt-get update
apt-get install nginx-extras
Π‘Π΅ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ° LuaJIT
apt-get -y install lua5.1 luajit-5.1 libluajit-5.1-dev
ΠΠ½ΡΡΠ°Π»ΠΈΡΠ°ΡΠ΅ Π½Π° imagemagick
apt-get -y install imagemagick
ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Π²ΠΎΠ»ΡΠ΅Π±Π½ΠΎ ΡΡΠ°ΠΏΡΠ΅ Π½Π° Π½Π΅Π³ΠΎ, Π²ΠΎ ΠΌΠΎΡΠΎΡ ΡΠ»ΡΡΠ°Ρ Π·Π° Π²Π΅ΡΠ·ΠΈΡΠ°ΡΠ° 6
apt-cache search libmagickwand
apt-get -y install libmagickwand-6.q16-3 libmagickwand-6.q16-dev
ΠΡΠ°Π΄Π΅ΡΠ΅ Π»ΡΠ°-ΠΈΠΌΠ°Π³ΠΈΠΊ
ΠΠΎ ΠΊΠ»ΠΎΠ½ΠΈΡΠ°ΠΌΠ΅ ΡΠΊΠ»Π°Π΄ΠΈΡΡΠ΅ΡΠΎ (ΠΈΠ»ΠΈ Π³ΠΎ Π·Π΅ΠΌΠ°ΠΌΠ΅ ΠΏΠ°ΡΠ΅Π½ΡΠΎΡ ΠΈ Π³ΠΎ ΠΎΡΠΏΠ°ΠΊΡΠ²Π°ΠΌΠ΅)
cd ~
git clone https://github.com/isage/lua-imagick.git
cd lua-imagick
mkdir build
cd build
cmake ..
make
make install
ΠΠΊΠΎ ΡΓ¨ Π±Π΅ΡΠ΅ Π΄ΠΎΠ±ΡΠΎ, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π³ΠΎ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠ°ΡΠ΅ Nginx.
ΠΠ΅ Π΄Π°Π΄Π°ΠΌ ΠΏΡΠΈΠΌΠ΅Ρ Π·Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΠ°ΡΠ° Π½Π° Π·Π°Π΄Π½ΠΈΠ½ΡΠΊΠΈΠΎΡ Ρ ΠΎΡΡ, ΠΊΠΎΡ, Π²ΡΡΡΠ½ΠΎΡΡ, Π΅ ΠΎΠ΄Π³ΠΎΠ²ΠΎΡΠ΅Π½ Π·Π° ΠΏΡΠΎΠΌΠ΅Π½Π° Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°ΡΠ°. Π’ΠΎΡ Π΅ ΠΏΡΠΎΠΊΡΠΈΡΠ°Π½ ΠΎΠ΄ ΠΏΡΠ΅Π΄Π½ΠΈΠΎΡ ΡΠ΅ΡΠ²Π΅Ρ, ΠΈΡΡΠΎ ΡΠ°ΠΊΠ° ΡΠΎ Nginx, ΠΊΠ°Π΄Π΅ ΡΡΠΎ ΠΊΠ΅ΡΠΈΡΠ°ΡΠ΅ΡΠΎ ΡΠ΅ ΡΠ»ΡΡΡΠ²Π° Π·Π° ΠΎΠ΄ΡΠ΅Π΄Π΅Π½ Π²ΡΠ΅ΠΌΠ΅Π½ΡΠΊΠΈ ΠΏΠ΅ΡΠΈΠΎΠ΄ (Π΄Π΅Π½ΠΎΠ²ΠΈ) ΠΈ Π΄ΡΡΠ³ΠΈ ΡΠ°Π±ΠΎΡΠΈ.
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
}
}
ΠΠ½Π° ΡΡΠΎ Π±Π΅ΡΠ΅ ΠΏΠΎΡΡΠ΅Π±Π½ΠΎ (ΠΏΡΠΎΡΠΈΡΡΠ²Π°ΡΠ΅ Π½Π° ΡΠ»ΠΈΠΊΠ°ΡΠ° ΠΎΠΊΠΎΠ»Ρ ΡΠ°Π±ΠΎΠ²ΠΈΡΠ΅) ΡΠ΅ ΡΠ»ΡΡΡΠ²Π° ΡΠΎ ΠΊΠΎΡΠΈΡΡΠ΅ΡΠ΅ img:extent()
ΠΈ ΡΠ΅ Π΄Π΅ΡΠΈΠ½ΠΈΡΠ° ΡΠΎ ΠΏΠΎΠΌΠΎΡ Π½Π° ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΠ°ΡΠΎΡ resize
ΡΠΎ Π·Π½Π°ΠΊ +
Π½Π° ΠΊΡΠ°ΡΠΎΡ.
ΠΠΎΡΡΠ°ΠΏΠ½ΠΈ ΡΠ΅ ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ ΠΎΠΏΡΠΈΠΈ:
- WxH (ΠΠ°Π΄ΡΠΆΠ΅ΡΠ΅ Π³ΠΎ ΡΠΎΠΎΠ΄Π½ΠΎΡΠΎΡ, ΠΊΠΎΡΠΈΡΡΠ΅ΡΠ΅ ΠΏΠΎΠ³ΠΎΠ»Π΅ΠΌΠ° Π΄ΠΈΠΌΠ΅Π½Π·ΠΈΡΠ°)
- WxH^ (ΠΠ°Π΄ΡΠΆΠ΅ΡΠ΅ Π³ΠΎ ΡΠΎΠΎΠ΄Π½ΠΎΡΠΎΡ, ΠΊΠΎΡΠΈΡΡΠ΅ΡΠ΅ ΠΏΠΎΠΌΠ°Π»Π° Π΄ΠΈΠΌΠ΅Π½Π·ΠΈΡΠ° (ΠΎΡΡΠ΅ΠΊΡΠ²Π°ΡΠ΅))
- WxH! (ΠΠ³Π½ΠΎΡΠΈΡΠ°Ρ Π³ΠΎ ΡΠΎΠΎΠ΄Π½ΠΎΡΠΎΡ)
- WxH+ (ΠΠ°Π΄ΡΠΆΠ΅ΡΠ΅ Π³ΠΎ ΡΠΎΠΎΠ΄Π½ΠΎΡΠΎΡ, Π΄ΠΎΠ΄Π°ΡΡΠ΅ ΡΡΡΠ°Π½ΠΈΡΠ½ΠΈ Π³ΡΠ°Π½ΠΈΡΠΈ)
ΠΠ±ΠΈΡΠ½Π° ΡΠ°Π±Π΅Π»Π° ΡΠΎ ΡΠ΅Π·ΡΠ»ΡΠ°ΡΠΈ ΠΎΠ΄ ΠΏΡΠΎΠΌΠ΅Π½Π° Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°ΡΠ°
ΠΠΎΠ±Π°ΡΠ°ΡΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΠ°Ρ uri
ΠΠ·Π»Π΅Π·Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π° Π½Π° ΡΠ»ΠΈΠΊΠ°ΡΠ°
?ΠΏΡΠΎΠΌΠ΅Π½Π° Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°=400Γ200
200 Γ 200
?resize=400Γ200^
400 Γ 400
?ΠΏΡΠΎΠΌΠ΅Π½Π° Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°=400Γ200!
400Γ200 (ΠΠ΅ ΠΏΡΠΎΠΏΠΎΡΡΠΈΠΎΠ½Π°Π»Π½ΠΎ)
?ΠΏΡΠΎΠΌΠ΅Π½Π° Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°=400Γ200+
400Γ200 (ΠΏΡΠΎΠΏΠΎΡΡΠΈΠΎΠ½Π°Π»Π½ΠΎ)
ΠΠΊΡΠΏΠ½ΠΎ
Π‘ΠΎ ΠΎΠ³Π»Π΅Π΄ Π½Π° ΠΌΠΎΡΡΠ° ΠΈ Π΅Π΄Π½ΠΎΡΡΠ°Π²Π½ΠΎΡΡΠ° Π½Π° ΠΎΠ²ΠΎΡ ΠΏΡΠΈΡΡΠ°ΠΏ, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½ΡΠΈΡΠ°ΡΠ΅ ΡΠ°Π±ΠΎΡΠΈ ΡΠΎ ΠΏΡΠΈΠ»ΠΈΡΠ½ΠΎ ΡΠ»ΠΎΠΆΠ΅Π½Π° Π»ΠΎΠ³ΠΈΠΊΠ°, Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, Π΄ΠΎΠ΄Π°Π²Π°ΡΠ΅ Π²ΠΎΠ΄Π΅Π½ΠΈ ΠΆΠΈΠ³ΠΎΠ²ΠΈ ΠΈΠ»ΠΈ ΡΠΏΡΠΎΠ²Π΅Π΄ΡΠ²Π°ΡΠ΅ ΠΎΠ²Π»Π°ΡΡΡΠ²Π°ΡΠ΅ ΡΠΎ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ ΠΏΡΠΈΡΡΠ°ΠΏ. ΠΠ° Π΄Π° Π³ΠΈ Π΄ΠΎΠ·Π½Π°Π΅ΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈΡΠ΅ Π½Π° API Π·Π° ΡΠ°Π±ΠΎΡΠ° ΡΠΎ ΡΠ»ΠΈΠΊΠΈ, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΡΠ΅ ΠΏΠΎΠ²ΠΈΠΊΠ°ΡΠ΅ Π½Π° Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΡΠ½Π°ΡΠ° Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡΠ°
ΠΠ·Π²ΠΎΡ: www.habr.com