แƒคแƒ แƒ”แƒœแƒ˜แƒก แƒ“แƒ แƒแƒก แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ˜แƒก แƒ–แƒแƒ›แƒ˜แƒก แƒจแƒ”แƒชแƒ•แƒšแƒ Nginx-แƒ˜แƒกแƒ แƒ“แƒ LuaJIT-แƒ˜แƒก (OpenResty) แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—

แƒฃแƒ™แƒ•แƒ” แƒกแƒแƒ™แƒ›แƒแƒแƒ“ แƒ“แƒ˜แƒ“แƒ˜ แƒฎแƒแƒœแƒ˜แƒ, แƒกแƒขแƒแƒขแƒ˜แƒ˜แƒ— แƒจแƒ—แƒแƒ’แƒแƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒจแƒ”แƒชแƒ•แƒแƒšแƒ”แƒ— แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ˜แƒก แƒ–แƒแƒ›แƒ แƒกแƒฃแƒ แƒแƒ—แƒ˜แƒก แƒ–แƒแƒ›แƒ˜แƒก แƒจแƒ”แƒชแƒ•แƒšแƒ แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ˜แƒงแƒ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— ngx_http_image_filter_module แƒ“แƒ แƒงแƒ•แƒ”แƒšแƒแƒคแƒ”แƒ แƒ˜ แƒ˜แƒกแƒ” แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ“แƒ, แƒ แƒแƒ’แƒแƒ แƒช แƒฃแƒœแƒ“แƒ. แƒ›แƒแƒ’แƒ แƒแƒ› แƒ”แƒ แƒ—แƒ˜ แƒžแƒ แƒแƒ‘แƒšแƒ”แƒ›แƒ แƒ’แƒแƒฉแƒœแƒ“แƒ, แƒ แƒแƒ“แƒ”แƒกแƒแƒช แƒ›แƒ”แƒœแƒ”แƒฏแƒ”แƒ แƒก แƒกแƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒแƒ“แƒ แƒ–แƒฃแƒกแƒขแƒ˜ แƒ–แƒแƒ›แƒ”แƒ‘แƒ˜แƒก แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ˜แƒก แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒ แƒ–แƒแƒ’แƒ˜แƒ”แƒ แƒ— แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒ–แƒ” แƒแƒกแƒแƒขแƒ•แƒ˜แƒ แƒ—แƒแƒ“, แƒ แƒแƒ“แƒ’แƒแƒœ... แƒ”แƒก แƒ˜แƒงแƒ แƒ›แƒแƒ—แƒ˜ แƒขแƒ”แƒฅแƒœแƒ˜แƒ™แƒฃแƒ แƒ˜ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ”แƒ‘แƒ˜. แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“, แƒ—แƒฃ แƒ’แƒ•แƒแƒฅแƒ•แƒก แƒ–แƒแƒ›แƒ˜แƒก แƒแƒ แƒ˜แƒ’แƒ˜แƒœแƒแƒšแƒฃแƒ แƒ˜ แƒ’แƒแƒ›แƒแƒกแƒแƒฎแƒฃแƒšแƒ”แƒ‘แƒ 1200 ร— 1200แƒ“แƒ แƒ–แƒแƒ›แƒ˜แƒก แƒจแƒ”แƒชแƒ•แƒšแƒ˜แƒกแƒแƒก แƒ•แƒฌแƒ”แƒ แƒ— แƒ แƒแƒฆแƒแƒชแƒแƒก แƒ–แƒแƒ›แƒ=600ร—400, แƒ›แƒแƒจแƒ˜แƒœ แƒ•แƒ˜แƒฆแƒ”แƒ‘แƒ— แƒžแƒ แƒแƒžแƒแƒ แƒชแƒ˜แƒฃแƒšแƒแƒ“ แƒจแƒ”แƒ›แƒชแƒ˜แƒ แƒ”แƒ‘แƒฃแƒš แƒกแƒฃแƒ แƒแƒ—แƒก แƒงแƒ•แƒ”แƒšแƒแƒ–แƒ” แƒžแƒแƒขแƒแƒ แƒ แƒ™แƒ˜แƒ“แƒ”แƒ–แƒ”, แƒ–แƒแƒ›แƒแƒ–แƒ” 400 ร— 400. แƒแƒกแƒ”แƒ•แƒ” แƒจแƒ”แƒฃแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒ˜แƒ แƒฃแƒคแƒ แƒ แƒ›แƒแƒฆแƒแƒšแƒ˜ แƒ’แƒแƒ แƒฉแƒ”แƒ•แƒแƒ“แƒแƒ‘แƒ˜แƒก (upscale) แƒ’แƒแƒ›แƒแƒกแƒแƒฎแƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒ. แƒ˜แƒ›แƒแƒ—. แƒ–แƒแƒ›แƒ=1500ร—1500 แƒ“แƒแƒแƒ‘แƒ แƒฃแƒœแƒ”แƒ‘แƒก แƒ˜แƒ’แƒ˜แƒ•แƒ” แƒกแƒฃแƒ แƒแƒ—แƒก 1200 ร— 1200

แƒ”แƒก แƒกแƒขแƒแƒขแƒ˜แƒ แƒ›แƒแƒ•แƒ˜แƒ“แƒ แƒกแƒแƒ›แƒแƒจแƒ•แƒ”แƒšแƒแƒจแƒ˜ OpenResty: NGINX-แƒ˜แƒก แƒกแƒ แƒฃแƒšแƒคแƒแƒกแƒแƒ•แƒแƒœ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒแƒ“ แƒ’แƒแƒ“แƒแƒฅแƒชแƒ”แƒ•แƒ แƒ˜แƒ›แƒ˜แƒก แƒ’แƒแƒ’แƒ”แƒ‘แƒ, แƒ—แƒฃ แƒ แƒแƒ’แƒแƒ  แƒ›แƒฃแƒจแƒแƒแƒ‘แƒก Nginx แƒšแƒฃแƒแƒกแƒ—แƒแƒœ แƒ“แƒ แƒ—แƒแƒ•แƒแƒ“ แƒ‘แƒ˜แƒ‘แƒšแƒ˜แƒแƒ—แƒ”แƒ™แƒ แƒšแƒฃแƒแƒกแƒ—แƒแƒœ isage/lua-imagick - Lua pure-c แƒแƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒก ImageMagick-แƒก. แƒ แƒแƒขแƒแƒ› แƒแƒ˜แƒ แƒฉแƒ˜แƒ”แƒก แƒ”แƒก แƒ’แƒแƒ›แƒแƒกแƒแƒ•แƒแƒšแƒ˜ แƒ“แƒ แƒแƒ แƒ, แƒ•แƒ—แƒฅแƒ•แƒแƒ—, แƒ แƒแƒฆแƒแƒช แƒžแƒ˜แƒ—แƒแƒœแƒจแƒ˜ - แƒ˜แƒ›แƒ˜แƒขแƒแƒ›, แƒ แƒแƒ› แƒ˜แƒก แƒกแƒฌแƒ แƒแƒคแƒ˜ แƒ“แƒ แƒ›แƒแƒกแƒแƒฎแƒ”แƒ แƒฎแƒ”แƒ‘แƒ”แƒšแƒ˜แƒ. แƒ—แƒฅแƒ•แƒ”แƒœ แƒแƒ แƒช แƒ™แƒ˜ แƒ’แƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒแƒ— แƒ แƒแƒ˜แƒ›แƒ” แƒคแƒแƒ˜แƒšแƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ, แƒงแƒ•แƒ”แƒšแƒแƒคแƒ”แƒ แƒ˜ แƒกแƒฌแƒแƒ แƒ˜แƒ Nginx แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒแƒจแƒ˜ (แƒกแƒฃแƒ แƒ•แƒ˜แƒšแƒ˜แƒกแƒแƒ›แƒ”แƒ‘แƒ ).

แƒ›แƒแƒจ แƒ แƒ แƒ’แƒ•แƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒ

แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ”แƒ‘แƒ˜ แƒ›แƒแƒงแƒ•แƒแƒœแƒ˜แƒšแƒ˜ แƒ˜แƒฅแƒœแƒ”แƒ‘แƒ Debian-แƒ–แƒ” แƒ“แƒแƒงแƒ แƒ“แƒœแƒแƒ‘แƒ˜แƒ—.

nginx-แƒ˜แƒกแƒ แƒ“แƒ nginx-extras-แƒ˜แƒก แƒ“แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ

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

แƒšแƒฃแƒ-แƒ˜แƒ›แƒแƒ’แƒ˜แƒ™แƒ˜แƒก แƒแƒ’แƒ”แƒ‘แƒ

แƒฉแƒ•แƒ”แƒœ แƒ•แƒแƒ™แƒšแƒ”แƒ‘แƒ— แƒกแƒแƒชแƒแƒ•แƒก (แƒแƒœ แƒแƒ•แƒ˜แƒฆแƒ”แƒ‘แƒ— zip-แƒก แƒ“แƒ แƒ•แƒฎแƒกแƒœแƒ˜แƒ— แƒ›แƒแƒก)

cd ~
git clone https://github.com/isage/lua-imagick.git
cd lua-imagick
mkdir build
cd build
cmake ..
make
make install

แƒ—แƒฃ แƒงแƒ•แƒ”แƒšแƒแƒคแƒ”แƒ แƒ˜ แƒ™แƒแƒ แƒ’แƒแƒ“ แƒฌแƒแƒ•แƒ˜แƒ“แƒ, แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— Nginx-แƒ˜แƒก แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒ.

แƒ›แƒ” แƒ›แƒ˜แƒ•แƒชแƒ”แƒ› แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒก backend แƒฐแƒแƒกแƒขแƒ˜แƒก แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช, แƒคแƒแƒฅแƒขแƒแƒ‘แƒ แƒ˜แƒ•แƒแƒ“, แƒžแƒแƒกแƒฃแƒฎแƒ˜แƒกแƒ›แƒ’แƒ”แƒ‘แƒ”แƒšแƒ˜แƒ แƒ–แƒแƒ›แƒ˜แƒก แƒจแƒ”แƒชแƒ•แƒšแƒแƒ–แƒ”. แƒ˜แƒ’แƒ˜ แƒžแƒ แƒแƒฅแƒกแƒ˜แƒ แƒ“แƒ”แƒ‘แƒ แƒฌแƒ˜แƒœแƒ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก แƒ›แƒ˜แƒ”แƒ , แƒแƒกแƒ”แƒ•แƒ” Nginx-แƒ˜แƒ—, แƒกแƒแƒ“แƒแƒช แƒฅแƒ”แƒจแƒ˜แƒ แƒ”แƒ‘แƒ แƒฎแƒ“แƒ”แƒ‘แƒ แƒ’แƒแƒ แƒ™แƒ•แƒ”แƒฃแƒšแƒ˜ แƒžแƒ”แƒ แƒ˜แƒแƒ“แƒ˜แƒก แƒ’แƒแƒœแƒ›แƒแƒ•แƒšแƒแƒ‘แƒแƒจแƒ˜ (แƒ“แƒฆแƒ”แƒ”แƒ‘แƒจแƒ˜) แƒ“แƒ แƒกแƒฎแƒ•แƒ แƒ แƒแƒ›.

nginx backend แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒ

# 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

?resize=400ร—200!
400ร—200 (แƒแƒ แƒแƒžแƒ แƒแƒžแƒแƒ แƒชแƒ˜แƒฃแƒšแƒ˜)

?resize=400ร—200+
400ร—200 (แƒžแƒ แƒแƒžแƒแƒ แƒชแƒ˜แƒฃแƒšแƒ˜)

แƒคแƒ แƒ”แƒœแƒ˜แƒก แƒ“แƒ แƒแƒก แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ˜แƒก แƒ–แƒแƒ›แƒ˜แƒก แƒจแƒ”แƒชแƒ•แƒšแƒ Nginx-แƒ˜แƒกแƒ แƒ“แƒ LuaJIT-แƒ˜แƒก (OpenResty) แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—

แƒกแƒฃแƒš

แƒแƒ› แƒ›แƒ˜แƒ“แƒ’แƒแƒ›แƒ˜แƒก แƒกแƒ˜แƒ›แƒซแƒšแƒแƒ•แƒ แƒ˜แƒกแƒ แƒ“แƒ แƒกแƒ˜แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ˜แƒก แƒ’แƒแƒ—แƒ•แƒแƒšแƒ˜แƒกแƒฌแƒ˜แƒœแƒ”แƒ‘แƒ˜แƒ—, แƒ—แƒฅแƒ•แƒ”แƒœ แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ’แƒแƒœแƒแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒแƒ— แƒกแƒแƒ’แƒœแƒ”แƒ‘แƒ˜ แƒกแƒแƒ™แƒ›แƒแƒแƒ“ แƒ แƒ—แƒฃแƒšแƒ˜ แƒšแƒแƒ’แƒ˜แƒ™แƒ˜แƒ—, แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“, แƒ“แƒแƒแƒ›แƒแƒขแƒแƒ— แƒฌแƒงแƒšแƒ˜แƒก แƒœแƒ˜แƒจแƒœแƒ”แƒ‘แƒ˜ แƒแƒœ แƒ’แƒแƒœแƒแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒแƒ— แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ แƒจแƒ”แƒ–แƒฆแƒฃแƒ“แƒฃแƒšแƒ˜ แƒฌแƒ•แƒ“แƒแƒ›แƒ˜แƒ—. แƒ˜แƒ›แƒ˜แƒกแƒแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒ› แƒ’แƒแƒ”แƒชแƒœแƒแƒ— API-แƒก แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ—แƒแƒœ แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒšแƒแƒ‘แƒ”แƒ‘แƒก, แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ›แƒ˜แƒ›แƒแƒ แƒ—แƒแƒ— แƒ‘แƒ˜แƒ‘แƒšแƒ˜แƒแƒ—แƒ”แƒ™แƒ˜แƒก แƒ“แƒแƒ™แƒฃแƒ›แƒ”แƒœแƒขแƒแƒชแƒ˜แƒแƒก isage/lua-imagick

แƒฌแƒงแƒแƒ แƒ: www.habr.com

แƒแƒฎแƒแƒšแƒ˜ แƒ™แƒแƒ›แƒ”แƒœแƒขแƒแƒ แƒ˜แƒก แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ