Skrydžio metu pakeiskite vaizdų dydį naudodami „Nginx“ ir „LuaJIT“ („OpenResty“)

Jau kurį laiką įkvėptas straipsnio Greitai pakeiskite vaizdų dydį vaizdo dydžio keitimas buvo sukonfigūruotas naudojant ngx_http_image_filter_module ir viskas veikė kaip priklauso. Tačiau viena problema iškilo, kai vadovui reikėjo gauti tikslių matmenų vaizdus įkelti į kai kurias paslaugas, nes... tai buvo jų techniniai reikalavimai. Pavyzdžiui, jei turime originalų dydžio vaizdą 1200 × 1200, o keisdami dydį rašome kažką panašaus ?resize=600×400, tada gauname proporcingai sumažintą vaizdą išilgai mažiausio krašto, dydžio 400 × 400. Taip pat neįmanoma gauti didesnės raiškos vaizdo (aukštesnės skalės). Tie. ?resize=1500×1500 grąžins tą patį vaizdą 1200 × 1200

Šis straipsnis atėjo į pagalbą OpenResty: paverčia NGINX visaverčiu programų serveriu suprasti, kaip „Nginx“ dirba su „Lua“ ir pačią „Lua“ biblioteką isage/lua-imagick - „Lua pure-c“ įrišimai „ImageMagick“. Kodėl pasirinktas šis sprendimas, o ne, tarkim, kažkas python – nes tai greita ir patogu. Jums net nereikia kurti jokių failų, viskas yra teisingai Nginx konfigūracijoje (neprivaloma).

Taigi ko mums reikia

Pavyzdžiai bus pateikti remiantis Debian.

„nginx“ ir „nginx-extra“ diegimas

apt-get update
apt-get install nginx-extras

„LuaJIT“ diegimas

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

Įdiegti imagemagick

apt-get -y install imagemagick

ir bibliotekos magickwand prie jo, mano atveju 6 versijai

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

Lua-imagick pastatymas

Klonuojame saugyklą (arba paimame užtrauktuką ir išpakuojame)

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

Jei viskas klostėsi gerai, galite konfigūruoti „Nginx“.

Pateiksiu pagrindinio kompiuterio, kuris iš tikrųjų yra atsakingas už dydžio keitimą, konfigūracijos pavyzdį. Jį palaiko priekinis serveris, taip pat ir Nginx, kur tam tikrą laiką (dienomis) vyksta talpyklos kaupimas ir kiti dalykai.

nginx backend konfigūracija

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

Tai, ko reikėjo (vaizdo išplėtimas aplink kraštus), nutinka naudojant img:extent() ir apibrėžiamas naudojant parametrą resize su ženklu + galų gale.

Galimos šios parinktys:

  • PxH (išlaikykite formato santykį, naudokite didesnį matmenį)
  • PxH^ (Išlaikykite formato santykį, naudokite mažesnį matmenį (apkarpymas))
  • PxH! (Ignoruoti formato santykį)
  • WxH+ (išlaikykite formato santykį, pridėkite šonines kraštines)

Suvestinė lentelė su dydžio keitimo rezultatais

Prašyti uri parametro
Išvesties vaizdo dydis

?resize=400×200
200 × 200

?resize=400×200^
400 × 400

?resize=400×200!
400 × 200 (neproporcinga)

?resize=400×200+
400 × 200 (proporcinga)

Skrydžio metu pakeiskite vaizdų dydį naudodami „Nginx“ ir „LuaJIT“ („OpenResty“)

Visas

Atsižvelgdami į šio požiūrio galią ir paprastumą, galite įgyvendinti gana sudėtingos logikos dalykus, pavyzdžiui, pridėti vandens ženklų arba įdiegti leidimą su ribota prieiga. Norėdami sužinoti API galimybes dirbti su vaizdais, galite peržiūrėti bibliotekos dokumentaciją isage/lua-imagick

Šaltinis: www.habr.com

Добавить комментарий