背景
目前而言,用移动端访问Web站点的用户越来越多,图片对流量的消耗是比较大的,之前一个用户用我们网站的app浏览的时候,2个小时耗去了2个G的流量,这是个很严重的问题,需要对图片进行压缩,减少对用户带宽的损耗。
方法
用户访问网站,上传图片,app端一律使用jpg格式压缩,不用png格式。
Niginx+lua+graphicsmagick
NIGINX配置:
location /images{
#图片防盗链配置
#valid_referers none blocked localhost *.mydomain.com;
#if ($invalid_referer)
#{
# return 403;
#} set $image_root /home/images;
set $file "$image_root$uri";
if (!-f $request_filename) {
rewrite_by_lua '
local index = string.find(ngx.var.uri, "([0-9]+)x([0-9]+)");
local originalUri = string.sub(ngx.var.uri, 0, index-2);
local area = string.sub(ngx.var.uri, index);
index = string.find(area, "([.])");
area = string.sub(area, 0, index-1);
function Split(szFullString, szSeparator)
local nFindStartIndex = 1
local nSplitIndex = 1
local nSplitArray = {}
while true do
local nFindLastIndex = string.find(szFullString, szSeparator, nFindStartIndex)
if not nFindLastIndex then
nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, string.len(szFullString))
break
end
nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, nFindLastIndex - 1)
nFindStartIndex = nFindLastIndex + string.len(szSeparator)
nSplitIndex = nSplitIndex + 1
end
return nSplitArray
end
local size_list = Split(area, "x"); function table.isLegal(table)
for _, value in pairs(table) do
if value % 10 ~= 0 then
return false
end
end
return true
end
local extend = string.sub(ngx.var.uri, -3,-1); if table.isLegal(size_list) and extend == "png" then
local command = [[/usr/local/GraphicsMagick-1.3.24/bin/gm convert -compress Lossless -quality 90 -density 72 -background none +profile "*" ]] .. ngx.var.image_root .. originalUri .. " -geometry " .. area .. "^ -gravity center -extent " .. area .. " " .. ngx.var.file;
os.execute(command); elseif table.isLegal(size_list) and extend ~= "png" then
local command = [[/usr/local/GraphicsMagick-1.3.24/bin/gm convert -compress Lossless -quality 90 -density 72 +profile "*" ]] .. ngx.var.image_root .. originalUri .. " -resize " .. area .. "^ -gravity center -extent " .. area .. " " .. ngx.var.file;
os.execute(command); else
ngx.exit(404);
end;
';
}}
/usr/local/GraphicsMagick-1.3.24/bin/gm convert -compress Lossless -quality 50 -background none +profile "*" /home/image/1.png -geometry 400^ -gravity center -extent 400 /home/image/2.jpg
用这种方法,可以将2M的png格式的大图片,压缩成为200KB的大小,非常有效。
之后我又对程序进行了优化,图片后面加上后缀.200x200.png,图片则会被压缩成200x200的png格式图片,如果加上.x.jpg,则会压缩成等比的jpg格式图片。
同时,nginx配置修改为
location /images {
set $image_root /home;
set $file "$image_root$uri";
if (!-f $request_filename) {
rewrite_by_lua_file /home/software/nginx-server/conf/image.lua;
}
alias /home/images;
expires max;
}
下面附上image.lua优化后的代码:
local extend = tostring(string.sub(ngx.var.uri, -3,-1));
local index = string.find(ngx.var.uri, "([0-9]+)x([0-9]+)");
local command;
if index == nil then
index = string.find(ngx.var.uri, "(%.x%.)")
if index == nil then
ngx.exit(404);
return;
end
local originalUri = string.sub(ngx.var.uri, 0, index-1);
if extend == "png" then
ngx.header.b="rr";
ngx.exit(404);
return;
elseif entend ~= "png" then
command = [[/usr/local/GraphicsMagick-1.3.24/bin/gm convert -quality 50 -density 72 +profile "*" ]] .. ngx.var.image_root .. originalUri .. " -gravity center " .. ngx.var.file;
end
ngx.header.a=command;
os.execute(command)
return
end
originalUri = string.sub(ngx.var.uri, 0, index-2);
local area = string.sub(ngx.var.uri, index);
index = string.find(area, "([.])");
area = string.sub(area, 0, index-1);
function Split(szFullString, szSeparator)
local nFindStartIndex = 1
local nSplitIndex = 1
local nSplitArray = {}
while true do
local nFindLastIndex = string.find(szFullString, szSeparator, nFindStartIndex)
if not nFindLastIndex then
nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, string.len(szFullString))
break
end
nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, nFindLastIndex - 1)
nFindStartIndex = nFindLastIndex + string.len(szSeparator)
nSplitIndex = nSplitIndex + 1
end
return nSplitArray
end
local size_list = Split(area, "x");
function table.isLegal(table)
for _, value in pairs(table) do
if value % 10 ~= 0 then
return false
end
end
return true
end
if table.isLegal(size_list) and extend == "png" then
command = [[/usr/local/GraphicsMagick-1.3.24/bin/gm convert -quality 50 -density 72 -background none +profile "*" ]] .. ngx.var.image_root .. originalUri .. " -geometry " .. area .. "^ -gravity center -extent " .. area .. " " .. ngx.var.file;
os.execute(command);
elseif table.isLegal(size_list) and extend ~= "png" then
command = [[/usr/local/GraphicsMagick-1.3.24/bin/gm convert -quality 50 -density 72 +profile "*" ]] .. ngx.var.image_root .. originalUri .. " -resize " .. area .. "^ -gravity center -extent " .. area .. " " .. ngx.var.file;
os.execute(command);
else
ngx.exit(404);
end;