背景

目前而言,用移动端访问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;

Web服务图片压缩,nginx+lua生成缩略图的更多相关文章

  1. 【Nginx】面试官竟然问我Nginx如何生成缩略图,还好我看了这篇文章!!

    写在前面 今天想写一篇使用Nginx如何生成缩略图的文章,想了半天题目也没想好,这个题目还是一名读者帮我起的.起因就是这位读者最近出去面试,面试官正好问了一个Nginx如何生成缩略图的问题.还别说,就 ...

  2. yii php 图片上传与生成缩略图

    今天需要做图片上传与生成缩略图的功能,把代码进行记录如下: html 视图              ($pic_action_url = $this->createAbsoluteUrl('h ...

  3. nginx实时生成缩略图到硬盘上

    现在随着各终端的出现(手机,ipad等平板),以及各种终端的手机分辨率和尺寸都不同,现在手机用户流量都是宝,网上出现了各种各样的生成缩略图功能的架构,有使用php实时生成缩略图的,也有用nginx + ...

  4. java图片裁剪和java生成缩略图

    一.缩略图 在浏览相冊的时候.可能须要生成相应的缩略图. 直接上代码: public class ImageUtil { private Logger log = LoggerFactory.getL ...

  5. Web服务(Apache、Nginx、Tomcat、Jetty)与应用(LAMP、CMS-WordPress&Ghost、Jenkins、Gitlab)

    Web服务和应用是目前信息技术领域的热门技术.如何使用Docker来运行常见的Web服务器(包括Apache.Nginx.Tomcat等),以及一些常用应用(LAMP.CMS等).包括具体的镜像构建方 ...

  6. php 图片操作类,支持生成缩略图,添加水印,上传缩略图

    <?php class Image {     //类开始     public $originimage = ""; //源图片文件地址     public $image ...

  7. nginx自动生成缩略图

    网站上常常一张图片,多个地方需要使用不同的尺寸,一般的方案是上传的时候,根据不同的尺寸用程序生成多张图片. 这么做有两个缺点: 1.如果需要新的尺寸图片的话,只能遍历下数据库,重新生成一次图片. 2. ...

  8. ASP.NET Web服务(ASMX)学习和代理生成

    第一步:按照http://www.c-sharpcorner.com/article/getting-started-with-asp-net-web-services-part-one/ 建立项目和 ...

  9. nginx 作为静态资源web服务

    Nginx作为静态资源web服务 静态资源web服务-CDN场景 Nginx资源存储中心会把静态资源分发给“北京Nginx”,“湖南Nginx”,“山东Nginx”. 然后北京User发送静态资源请求 ...

随机推荐

  1. 2句代码轻松实现WPF最大化不遮挡任务栏并且具有边框调节效果

    原文:2句代码轻松实现WPF最大化不遮挡任务栏并且具有边框调节效果 相信刚入门的菜鸟跟我一样找遍了百度谷歌解决最大化遮挡任务栏的方法大多方法都是HOOK一大堆API声明 最近在敲代码的时候无意中发现有 ...

  2. 查看Redis信息和状态

    原文转自:http://redisdoc.com/server/info.html INFO [section] 以一种易于解释(parse)且易于阅读的格式,返回关于 Redis 服务器的各种信息和 ...

  3. RC隔离 更新where条件列 没有索引的情况

    CREATE TABLE `test100` ( `sn` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增编号', `phoneNo` int(11) , `c ...

  4. Squares(哈希)

    Time Limit: 3500MS   Memory Limit: 65536K Total Submissions: 14328   Accepted: 5393 Description A sq ...

  5. Linux Shell编程(3)——运行shell脚本

    写完一个脚本,你能够运行它用命令:sh scriptname, [5] 另外也也可以用bash scriptname. 来执行(不推荐使用:sh <scriptname, 因为这样会禁止脚本从标 ...

  6. datagridview,textbox,combobox的数据绑定,数据赋值,picturebox的用法

    一:datagridview数据绑定 二:textbox的数据绑定(datetimepicker) 总结: 最好还是写成双向绑定那种,不要再写出发事件了,只要在给textbox赋值就能重新绑定了,不然 ...

  7. HDOJ(HDU) 2503 a/b + c/d(最大公约数问题)

    Problem Description 给你2个分数,求他们的和,并要求和为最简形式. Input 输入首先包含一个正整数T(T<=1000),表示有T组测试数据,然后是T行数据,每行包含四个正 ...

  8. python多线程机制

    Python中的线程从一开始就是操作系统的原生线程.而Python虚拟机也同样使用一个全局解释器锁(Global Interpreter Lock,GIL)来互斥线程多Python虚拟机的使用. GI ...

  9. python 发送邮件例子

    想到用python发送邮件 主要是服务器 有时候会产生coredump文件  ,然后因为脚本重启原因,服务器coredump产生后会重启 但是没有主动通知开发人员 想了下可以写个脚本一旦产生cored ...

  10. javascript中错误使用var造成undefined

    在javascript中依据变量作用的范围不同分为局部变量和全局变量,直接定义的变量是全局变量,全局变量能够被全部的脚本訪问:在函数中定义的变量是局部变量,局部变量仅仅在函数内有效. 假设全局变量和局 ...