背景
目前而言,用移動端訪問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;