• Web服务图片压缩,nginx+lua生成缩略图


    背景

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


  • 相关阅读:
    vue-music 关于搜索历史本地存储
    Node.js中package.json中^和~的区别
    主流浏览器内核
    pm2 日常使用
    前端验证用户登陆状态(vue.js)
    ng-repeat循环出来的部分调用同一个函数并且实现每个模块之间不能相互干扰
    行内元素垂直方向位置调整的一些感悟和困惑
    由overflow-x:scroll产生的收获
    子代选择器(>)后代选择器(' ')的区别
    content相关属性
  • 原文地址:https://www.cnblogs.com/uwannerme/p/5692862.html
Copyright © 2020-2023  润新知