NGINX+Lua=Size_img

Изменение размера картинки на лету в nginx

Вариант №1 с возможностью упасть в ошибку

nginx.conf
  location / {
    lua_code_cache on;
    try_files $uri @invalid;
    content_by_lua_block {
      local magick = require("magick")
      local images_dir = "/some-dir-in-dir-images"
      local function return_not_found(msg)
        ngx.status = ngx.HTTP_NOT_FOUND
        ngx.header["Content-type"] = "text/html"
        ngx.say(msg)
        ngx.exit(0)
      end
      ngx.header["Content-Type"] = "image/jpeg;"
      local w, h, path = ngx.var.arg_w, ngx.var.arg_h, ngx.var.uri
      if w == nil or h == nil then
        return_not_found("invalid signature")
      end
      local size = w .. "x" .. h
      local source_fname = images_dir .. path
      ngx.print(magick.thumb(source_fname, size))
    }
  }
  location @invalid {
      content_by_lua_block {
        ngx.status = ngx.HTTP_BAD_REQUEST
      }
  }

Вариант №2 при не заданных параметрах, подставляет оригинал

ngunx.conf
  location / {
    lua_code_cache on;
    try_files $uri @invalid;
    content_by_lua_block {
      local magick = require("magick")
      local images_dir = "/some-dir-in-dir-images"
      local w, h, path = ngx.var.arg_w, ngx.var.arg_h, ngx.var.uri
      local source_fname = images_dir .. path
      local img = magick.load_image(source_fname)
      if w == nil and h == nil then
        local w = img:get_width()
        local h = img:get_height()
        local size = w .. "x" .. h
        ngx.header["Content-Type"] = "image/jpeg;"
        ngx.print(magick.thumb(source_fname, size))
        ngx.exit(0)
      end
      if w == nil then
        local w = img:get_width()
        local size = w .. "x" .. h
        ngx.header["Content-Type"] = "image/jpeg;"
        ngx.print(magick.thumb(source_fname, size))
        ngx.exit(0)
      end
      if h == nil then
        local h = img:get_height()
        local size = w .. "x" .. h
        ngx.header["Content-Type"] = "image/jpeg;"
        ngx.print(magick.thumb(source_fname, size))
        ngx.exit(0)
      end
      local size = w .. "x" .. h
      if size == "x" then
        local w = img:get_width()
        local h = img:get_height()
        local size = w .. "x" .. h
        ngx.header["Content-Type"] = "image/jpeg;"
        ngx.print(magick.thumb(source_fname, size))
        ngx.exit(0)
      end
      ngx.header["Content-Type"] = "image/jpeg;"
      ngx.print(magick.thumb(source_fname, size))
    }
  }
  location @invalid {
      content_by_lua_block {
        ngx.status = ngx.HTTP_BAD_REQUEST
      }
  }

Вариант 3 с учетом важности заданного параметра

nginx.conf
  location / {
    lua_code_cache on;
    try_files $uri @invalid;
    content_by_lua_block {
      local magick = require("magick")
      local images_dir = "/some-dir-in-dir-images"
      local w, h, path = ngx.var.arg_w, ngx.var.arg_h, ngx.var.uri
      local source_fname = images_dir .. path
      local img = magick.load_image(source_fname)
      if w == nil and h == nil then
        local size = 0 .. "x" .. 0
        ngx.header["Content-Type"] = "image/jpeg;"
        ngx.print(magick.thumb(source_fname, size))
        ngx.exit(0)
      elseif w == nil then
        local size = "x" .. h
        ngx.header["Content-Type"] = "image/jpeg;"
        ngx.print(magick.thumb(source_fname, size))
        ngx.exit(0)
      elseif h == nil then
        local size = w .. "x"
        ngx.header["Content-Type"] = "image/jpeg;"
        ngx.print(magick.thumb(source_fname, size))
        ngx.exit(0)
      end
      local size = w .. "x" .. h
      if size == "x" then
        local w = img:get_width()
        local h = img:get_height()
        local size = w .. "x" .. h
        ngx.header["Content-Type"] = "image/jpeg;"
        ngx.print(magick.thumb(source_fname, size))
        ngx.exit(0)
      end
      ngx.header["Content-Type"] = "image/jpeg;"
      ngx.print(magick.thumb(source_fname, size))
    }
  }
  location @invalid {
      content_by_lua_block {
        ngx.status = ngx.HTTP_BAD_REQUEST
      }
  }

Вариант 3.1 с использованием функции

nginx.conf
  location / {
    add_header Cache-Control public;
    expires max;
    lua_code_cache on;
    try_files $uri @invalid;
    content_by_lua_block {
      local magick = require("magick")
      local md5 = require("md5")
      local images_dir = "/some-dir-in-dir-images"
      local w, h, path = ngx.var.arg_w, ngx.var.arg_h, ngx.var.uri
      local source_fname = images_dir .. path
      local function return_img(size)
        ngx.header["Content-Type"] = "image/jpeg;"
        ngx.header["ETag"] = md5.sumhexa(source_fname .. size)
        ngx.header.Last_Modified = os.date("%a, %d %b %Y %H:%M:%S GMT", os.time())
        ngx.print(magick.thumb(source_fname, size))
        ngx.exit(0)
      end
      if w == nil and h == nil then
        local size = 0 .. "x" .. 0
        return_img(size)
      elseif w == nil then
        local size = "x" .. h
        return_img(size)
      elseif h == nil then
        local size = w .. "x"
        return_img(size)
      end
      local size = w .. "x" .. h
      if size == "x" then
        local size = 0 .. "x" .. 0
        return_img(size)
      end
        return_img(size)
    }
  }
  location @invalid {
      content_by_lua_block {
        ngx.status = ngx.HTTP_BAD_REQUEST
      }
  }

Exampel url:

http://localhost/some-dir-in-dir-images/images?w=100&h=100

Last updated