Nginx ve LuaJIT (OpenResty) kullanarak görüntüleri anında yeniden boyutlandırın

Bir süredir makaleden ilham alıyorum Görüntü anında yeniden boyutlandırma görüntü yeniden boyutlandırma kullanılarak yapılandırıldı ngx_http_image_filter_module ve her şey olması gerektiği gibi çalıştı. Ancak yöneticinin bazı hizmetlere yüklemek için tam boyutlu görseller alması gerektiğinde bir sorun ortaya çıktı, çünkü... bunlar onların teknik gereksinimleriydi. Örneğin, orijinal boyutta bir görselimiz varsa 1200 × 1200ve yeniden boyutlandırırken şöyle bir şey yazarız: ?yeniden boyutlandırma=600×400, daha sonra en küçük kenar boyunca orantılı olarak küçültülmüş bir görüntü elde ederiz, boyut 400 × 400. Daha yüksek çözünürlüklü (upscale) bir görüntü elde etmek de mümkün değildir. Onlar. ?yeniden boyutlandırma=1500×1500 aynı görüntüyü döndürecek 1200 × 1200

Bu makale kurtarmaya geldi OpenResty: NGINX'i tam teşekküllü bir uygulama sunucusuna dönüştürmek Nginx'in Lua ile nasıl çalıştığını ve Lua için kütüphanenin kendisini anlamak isage/lua-imagick - Lua pure-c, ImageMagick'e bağlanır. Bu çözüm neden python'da bir şey değil de seçildi - çünkü hızlı ve kullanışlı. Herhangi bir dosya oluşturmanıza bile gerek yok, Nginx yapılandırmasında her şey doğru (isteğe bağlı).

Peki neye ihtiyacımız var

Örnekler Debian temel alınarak verilecektir.

Nginx ve nginx-extras'ı yükleme

apt-get update
apt-get install nginx-extras

LuaJIT'i yükleme

apt-get -y install lua5.1 luajit-5.1 libluajit-5.1-dev

imagemagick'i yükleme

apt-get -y install imagemagick

ve kütüphaneler sihirli değnek buna göre, benim durumumda sürüm 6 için

apt-cache search libmagickwand
apt-get -y install libmagickwand-6.q16-3 libmagickwand-6.q16-dev

Lua-imagick'i inşa etmek

Depoyu klonlarız (veya zip'i alıp paketini açarız)

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

Her şey yolunda giderse Nginx'i yapılandırabilirsiniz.

Aslında yeniden boyutlandırmadan sorumlu olan arka uç ana bilgisayarın yapılandırmasına bir örnek vereceğim. Ön sunucu tarafından ve ayrıca Nginx ile proxy sağlanır, burada önbellekleme belirli bir süre (günler) boyunca ve diğer şeyler için gerçekleşir.

nginx arka uç yapılandırması

# 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
    }
}

Gereken şey (görüntünün kenarlardan genişletilmesi) kullanılarak gerçekleşir. img:extent() ve parametre kullanılarak tanımlanır resize bir işaret ile + sonunda.

Aşağıdaki seçenekler mevcuttur:

  • GxY (En boy oranını koruyun, daha yüksek boyut kullanın)
  • GxY^ (En boy oranını koruyun, daha düşük boyut kullanın (kırpın))
  • WxH! (En-boy oranını göz ardı edin)
  • GxY+ (En boy oranını koruyun, yan kenarlıklar ekleyin)

Yeniden boyutlandırma sonuçlarını içeren özet tablosu

Uri parametresini iste
Çıktı Görüntü Boyutu

?yeniden boyutlandırma=400×200
200 × 200

?yeniden boyutlandır=400×200^
400 × 400

?yeniden boyutlandır=400×200!
400×200 (Orantılı değil)

?yeniden boyutlandır=400×200+
400×200 (Orantılı)

Nginx ve LuaJIT (OpenResty) kullanarak görüntüleri anında yeniden boyutlandırın

sonuç

Bu yaklaşımın gücü ve basitliği göz önüne alındığında, filigran eklemek veya sınırlı erişimle yetkilendirme uygulamak gibi oldukça karmaşık mantıkla işlemleri gerçekleştirebilirsiniz. API'nin görüntülerle çalışma yeteneklerini öğrenmek için kitaplık belgelerine başvurabilirsiniz. isage/lua-imagick

Kaynak: habr.com

Yorum ekle