Muuta kuvien kokoa lennossa Nginxillä ja LuaJITillä (OpenResty)

Jo jonkin aikaa artikkelin inspiroimana Kuvan koon muuttaminen lennossa kuvan koon muuttaminen määritettiin käyttämällä ngx_http_image_filter_module ja kaikki toimi niinkuin piti. Mutta yksi ongelma ilmeni, kun johtajan piti saada tarkkoja mittoja sisältäviä kuvia ladatakseen joihinkin palveluihin, koska... nämä olivat heidän tekniset vaatimukset. Esimerkiksi, jos meillä on alkuperäinen kokoinen kuva 1200 × 1200, ja kokoa muuttaessa kirjoitamme jotain tällaista ?resize=600×400, niin saadaan suhteellisesti pienennetty kuva pienintä reunaa pitkin, koko 400 × 400. On myös mahdotonta saada kuvaa korkeammalla resoluutiolla (parempi skaalaus). Nuo. ?resize=1500×1500 palauttaa saman kuvan 1200 × 1200

Tämä artikkeli tuli apuun OpenResty: NGINX:n muuttaminen täysimittaiseksi sovelluspalvelimeksi ymmärtääksesi kuinka Nginx toimii Luan kanssa ja itse Luan kirjasto isage/lua-imagick - Lua pure-c -sidokset ImageMagickiin. Miksi valittiin tämä ratkaisu, ei esimerkiksi jokin pythonissa - koska se on nopea ja kätevä. Sinun ei tarvitse edes luoda tiedostoja, kaikki on oikein Nginx-kokoonpanossa (valinnainen).

Joten mitä me tarvitsemme

Esimerkkejä annetaan Debianin pohjalta.

Asenna nginx ja nginx-extrat

apt-get update
apt-get install nginx-extras

LuaJITin asennus

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

Imagemagickin asennus

apt-get -y install imagemagick

ja kirjastot taikasauva siihen, minun tapauksessani versioon 6

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

Lua-imagickin rakentaminen

Kloonamme arkiston (tai otamme zip:n ja puramme sen)

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

Jos kaikki meni hyvin, voit määrittää Nginxin.

Annan esimerkin taustapalvelimen kokoonpanosta, joka itse asiassa on vastuussa koon muuttamisesta. Sitä välittää etupalvelin, myös Nginxillä, jossa välimuistia tapahtuu tietyn ajan (päiviä) ja muuta.

nginx-taustajärjestelmän asetukset

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

Se mitä vaadittiin (kuvan laajentaminen reunojen ympärille) tapahtuu käyttämällä img:extent() ja se määritellään parametrilla resize merkin kanssa + lopussa.

Seuraavat vaihtoehdot ovat käytettävissä:

  • LxK (Säilytä kuvasuhde, käytä suurempaa ulottuvuutta)
  • LxK^ (Säilytä kuvasuhde, käytä pienempää mittaa (rajaa))
  • LxK! (Ohita kuvasuhde)
  • LxK+ (Säilytä kuvasuhde, lisää sivureunukset)

Yhteenvetotaulukko koonmuutostuloksista

Pyydä uri-parametria
Tulostuskuvan koko

?resize=400×200
200 × 200

?resize=400×200^
400 × 400

?resize=400×200!
400 × 200 (ei suhteellinen)

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

Muuta kuvien kokoa lennossa Nginxillä ja LuaJITillä (OpenResty)

Koko

Ottaen huomioon tämän lähestymistavan tehon ja yksinkertaisuuden, voit toteuttaa asioita melko monimutkaisella logiikalla, esimerkiksi lisäämällä vesileimoja tai toteuttamalla valtuutuksen rajoitetulla pääsyllä. Saadaksesi selville API:n ominaisuudet kuvien kanssa työskentelemiseen, voit katsoa kirjaston dokumentaatiota isage/lua-imagick

Lähde: will.com

Lisää kommentti