Skip to content

Instantly share code, notes, and snippets.

@sergeyfedotov
Last active September 2, 2019 17:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save sergeyfedotov/5a4465d5094a0851314bd2a93179c56c to your computer and use it in GitHub Desktop.
Save sergeyfedotov/5a4465d5094a0851314bd2a93179c56c to your computer and use it in GitHub Desktop.
Nginx + Lua image resize
# ...
location ~ ^/image/(.*)$ {
try_files $uri @resizer;
}
location @resizer {
secure_link $arg_s;
secure_link_md5 "$1 secret_word";
if ($secure_link = "") {
return 403;
}
proxy_pass http://127.0.0.1:81/$1;
proxy_buffering on;
proxy_store on;
proxy_set_header Host $host;
}
# ...
user nginx;
worker_processes auto;
error_log /dev/stderr warn;
pid /var/run/nginx.pid;
events {
worker_connections 256;
}
http {
access_log /dev/stdout;
lua_code_cache on;
lua_package_path 'conf/?.lua;;';
init_by_lua_block {
magick = require 'magick'
math = require 'math'
}
server {
listen 81;
location ~ ^/(?<filter>resize|fit)/(?<width>\d+)x(?<height>\d+)/(?<path>.+)\.(?<format>jpg|png)$ {
set $path "/var/uploads/$path";
content_by_lua_file /srv/resizer.lua;
}
}
}
ngx.req.discard_body()
local filter, path, format = ngx.var.filter, ngx.var.path, ngx.var.format
local width, height = tonumber(ngx.var.width), tonumber(ngx.var.height)
local img, error = magick.load_image(path)
if img == nil then
ngx.log(ngx.ERR, error)
return ngx.exit(415)
end
img:auto_orient()
if filter == 'fit' then
img:resize_and_crop(width, height)
else
local w, h = img:get_width(), img:get_height()
local scale = math.min(width / w, height / h)
img:resize(w * scale, h * scale)
end
if img:get_width() < 150 and img:get_height() < 150 then
img:sharpen(1, 0)
end
if format == 'png' then
img:set_format('png')
else
img:set_format('jpeg')
end
img:set_quality(85)
img:set_interlace_scheme('PlaneInterlace')
img:strip()
ngx.print(img:get_blob())
return ngx.exit(ngx.HTTP_OK)
<?php
if (!function_exists('base64url_encode')) {
function base64url_encode($data)
{
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
}
const SECRET_WORD = 'secret_word';
function get_path_sign($path)
{
return base64url_encode(md5($path.SECRET_WORD, true));
}
$path = 'resize/640x480/test.jpg';
printf('<img src="/image/%s?s=%s"/>', $path, get_path_sign($path)); // -> /image/resize/640x480/test.jpg?s=...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment