nginx lua fastdfs动态缩略图

1.安装软件基础包

useradd -r nginx -s /sbin/nologin
yum -y install epel-release git
yum install -y gcc gcc-c++ zlib zlib-devel openssl openssl-devel pcre pcre-devel gd-devel
yum install -y libpng libjpeg libpng-devel libjpeg-devel ghostscript libtiff libtiff-devel freetype freetype-devel readline-devel ncurses-devel

 2.下载相关软件,其中nginx-http-concat和echo-nginx-module模块非必须

git clone https://github.com/alibaba/nginx-http-concat.git
git clone https://github.com/simpl/ngx_devel_kit.git
git clone https://github.com/openresty/echo-nginx-module.git
git clone https://github.com/openresty/lua-nginx-module.git

# 安装LuaJIT
cd /usr/local/src
wget http://luajit.org/download/LuaJIT-2.0.4.tar.gz
tar -zxf LuaJIT-2.0.4.tar.gz
cd LuaJIT-2.0.4
make 
make install 
export LUAJIT_LIB=/usr/local/lib
export LUAJIT_INC=/usr/local/include/luajit-2.0
ln -s /usr/local/lib/libluajit-5.1.so.2 /lib64/libluajit-5.1.so.2

# 安装Lua
cd /usr/local/src
wget http://www.lua.org/ftp/lua-5.3.1.tar.gz  
tar -zxvpf lua-5.3.1.tar.gz
cd lua-5.3.1
make linux && make install

# 安装GM
cd /usr/local/src
wget ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/1.3/GraphicsMagick-1.3.18.tar.gz
tar -zxvf GraphicsMagick-1.3.18.tar.gz
cd GraphicsMagick-1.3.18
./configure --prefix=/usr/local/GraphicsMagick-1.3.18 --enable-shared
make  && make install
ln -s /usr/local/GraphicsMagick-1.3.18 /usr/local/GraphicsMagick

# 安装nginx
cd /usr/local/src
wget http://nginx.org/download/nginx-1.10.2.tar.gz
tar -zxvf nginx-1.10.2.tar.gz
cd nginx-1.10.2
./configure --prefix=/usr/local/nginx-1.10.2 \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_sub_module \
--with-http_flv_module \
--with-http_dav_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--with-http_addition_module \
--add-module=/usr/local/src/fastdfs-nginx-module/src \
--with-http_image_filter_module \
--with-pcre \
--add-module=../nginx-http-concat \
--add-module=../lua-nginx-module \
--add-module=../ngx_devel_kit \
--add-module=../echo-nginx-module \
--with-ld-opt=-Wl,-rpath,$LUAJIT_LIB 

make
make install

ln -s /usr/local/nginx-1.10.2 /usr/local/nginx

 

 3.第一种情况:普通上传的文件生成缩略图

  a. 准备gm的lua脚本

cd /usr/local/nginx/conf/
mkdir lua

# GM的lua脚本
vim ImageResizer.lua
local command = "/usr/local/GraphicsMagick/bin/gm convert   -auto-orient -strip " .. ngx.var.request_filepath .. " -resize " .. ngx.var.width .. "x" .. ngx.var.height .. " +profile \"*\" " .
. ngx.var.request_filepath .. "_" .. ngx.var.width .. "x" .. ngx.var.height .. "." .. ngx.var.ext;
os.execute(command);
ngx.exec(ngx.var.request_uri);

  a-a.缩略图生成限定尺寸

-- 生成指定尺寸
local area=ngx.var.width .. "x" .. ngx.var.height;
-- local image_sizes = {"100x100", "150x150", "200x200", "300x300", "400x400","600x600","800x800"};
local image_sizes = {"50x50","100x100", "150x150", "200x200", "300x300", "400x400","600x600","800x800"};
function table.contains(table, element)  
    for _, value in pairs(table) do  
        if value == element then
            return true  
        end  
    end  
    return false  
end 

-- 生成缩略图
if table.contains(image_sizes, area) then  
	local command = "/usr/local/GraphicsMagick/bin/gm convert -quality 90  -auto-orient -strip " .. ngx.var.request_filepath .. " -resize " .. area .. " +profile \"*\" " .. ngx.var.request_filepath .. "_" .. area .. "." .. ngx.var.ext;
	os.execute(command);    
	ngx.exec(ngx.var.request_uri);
else
	ngx.exit(404)
end;

b.修改nginx配置文件

   server {
        listen       80;
        server_name  192.168.1.19;
        root /data/attached/b2b;
  
        location /lua1 {
        default_type 'text/plain';
        content_by_lua 'ngx.say("hello, lua")';
        }
  
  
          location ~* ^(.+\.(jpg|jpeg|gif|png))_(\d+)x(\d+)\.(jpg|jpeg|gif|png)$ {
                root /data/attached/b2b;
                if (!-f $request_filename) {    	             # 如果文件不存在时才需要裁剪
                        add_header X-Powered-By 'Lua GraphicsMagick';# 此 HTTP Header 无实际意义,用于测试
                        add_header file-path $request_filename;      # 此 HTTP Header 无实际意义,用于测试
                        #lua_code_cache off;                         # 在编写外部 Lua 脚本时,设置为 off Nginx 不会缓存 Lua,方便调试
                        set $request_filepath /data/attached/b2b$1;  # 设置原始图片路径,如:/document_root/1.gif
                        set $width $3;                               # 设置裁剪/缩放的宽度
                        set $height $4;                              # 设置裁剪/缩放的高度
                        set $ext $5;                                 # 图片文件格式后缀
                        content_by_lua_file /usr/local/nginx/conf/lua/ImageResizer.lua;    # 加载外部 Lua 文件
                }
  
  
        }
}

   c.图片目录赋予网站用户写的权限

chown nginx.nginx /data/attached/
/usr/local/nginx/sbin/nginx -t
/usr/local/nginx/sbin/nginx -s reload

   d.查看原图

  e.缩略图

 4.第二种情况:fastdfs上传的文件生成缩略图

   a.下载lua脚本到/usr/local/nginx/conf/lua目录下

git clone https://github.com/hpxl/nginx-lua-fastdfs-GraphicsMagick.git
cd nginx-lua-fastdfs-GraphicsMagick/lua
cp ./* /usr/local/nginx/conf/lua/

cd /usr/local/nginx/conf/lua/
vim fastdfs.lua                 # 46行配置tracker的地址,72行配置gm的命令变量
 46     fdfs:set_tracker("10.160.43.105", 22122)
 47     fdfs:set_timeout(1000)
 48     fdfs:set_tracker_keepalive(0, 100)
 49     fdfs:set_storage_keepalive(0, 100)
 50     local data = fdfs:do_download(fileid)
 51     if data then
 52        -- check image dir
 53         if not is_dir(ngx.var.image_dir) then
 54             os.execute("mkdir -p " .. ngx.var.image_dir)
 55         end
 56         writefile(originalFile, data)
 57     end
 58 end
 59 
 60 -- 创建缩略图
 61 local image_sizes = {"80x80", "800x600", "40x40", "60x60"};
 62 function table.contains(table, element)  
 63     for _, value in pairs(table) do
 64         if value == element then
 65             return true  
 66         end  
 67     end
 68     return false
 69 end 
 70 
 71 if table.contains(image_sizes, area) then
 72     local command = "/usr/local/GraphicsMagick/bin/gm convert " .. originalFile  .. " -thumbnail " .. area .. " -background gray -gravity center -extent " .. area .. " " .. ngx.var.file;
      
 73     os.execute(command);
 74 end;
 75 
 76 if file_exists(ngx.var.file) then
 77     --ngx.req.set_uri(ngx.var.uri, true);  
 78     ngx.exec(ngx.var.uri)
 79 else
 80     ngx.exit(404)
 81 end

  a-a.上传的透明PNG图片生成缩略图,默认会有白色或黑色底,需要去掉,修改fastdfs.lua脚本

-- 写入文件
local function writefile(filename, info)
    local wfile=io.open(filename, "w") --写入文件(w覆盖)
    assert(wfile)  --打开时验证是否出错		
    wfile:write(info)  --写入传入的内容
    wfile:close()  --调用结束后记得关闭
end

-- 检测路径是否目录
local function is_dir(sPath)
    if type(sPath) ~= "string" then return false end

    local response = os.execute( "cd " .. sPath )
    if response == 0 then
        return true
    end
    return false
end

-- 检测文件是否存在
local file_exists = function(name)
    local f=io.open(name,"r")
    if f~=nil then io.close(f) return true else return false end
end

local area = nil
local originalUri = ngx.var.uri;
local originalFile = ngx.var.file;
local index = string.find(ngx.var.uri, "([0-9]+)x([0-9]+)");  
if index then 
    originalUri = string.sub(ngx.var.uri, 0, index-2);  
    area = string.sub(ngx.var.uri, index);  
    index = string.find(area, "([.])");  
    area = string.sub(area, 0, index-1);  

    local index = string.find(originalFile, "([0-9]+)x([0-9]+)");  
    originalFile = string.sub(originalFile, 0, index-2)
end

-- check original file
if not file_exists(originalFile) then
    local fileid = string.sub(originalUri, 2);
    -- main
    local fastdfs = require('restyfastdfs')
    local fdfs = fastdfs:new()
    fdfs:set_tracker("10.1.8.43", 22122)
    fdfs:set_tracker("10.1.8.44", 22122)
    fdfs:set_timeout(1000)
    fdfs:set_tracker_keepalive(0, 100)
    fdfs:set_storage_keepalive(0, 100)
    local data = fdfs:do_download(fileid)
    if data then
       -- check image dir
        if not is_dir(ngx.var.image_dir) then
            os.execute("mkdir -p " .. ngx.var.image_dir)
        end
        writefile(originalFile, data)
    end
end

-- 创建缩略图
local image_sizes = {"50x50", "100x100", "400x400", "640x320","600x600","240x150"};  
function table.contains(table, element)  
    for _, value in pairs(table) do  
        if value == element then
            return true  
        end  
    end  
    return false  
end 

if table.contains(image_sizes, area) then  
    -- 判断一下
    local bg;
    if string.lower(string.sub(ngx.var.file,-3))=="jpg" then
        bg=" -background white ";
    else
        bg=" -background transparent ";
    end;
    local command = "/usr/local/GraphicsMagick/bin/gm convert " .. originalFile  .. " -thumbnail " .. area .. bg .. " -gravity center -extent " .. area .. " " .. ngx.var.file;  
    os.execute(command);  
end;

if file_exists(ngx.var.file) then
    --ngx.req.set_uri(ngx.var.uri, true);  
    ngx.exec(ngx.var.uri)
else
    ngx.exit(404)
end

    a-b .上传的图片有些生成缩略图生成不了,需要更改脚本,出差如下

 

-- 写入文件
local function writefile(filename, info)
    local wfile=io.open(filename, "w") --写入文件(w覆盖)
    assert(wfile)  --打开时验证是否出错		
    wfile:write(info)  --写入传入的内容
    wfile:close()  --调用结束后记得关闭
end

-- 检测路径是否目录
local function is_dir(sPath)
    if type(sPath) ~= "string" then return false end

    local response = os.execute( "cd " .. sPath )
    if response == 0 then
        return true
    end
    return false
end

-- 检测文件是否存在
local file_exists = function(name)
    local f=io.open(name,"r")
    if f~=nil then io.close(f) return true else return false end
end

-- 反向查找路径
function last_find(str, k)
	local ts = string.reverse(str);
	local _, i = string.find(ts, k);
    return string.len(ts) - i + 1;
end

local area = nil
local originalUri = ngx.var.uri;
local originalFile = ngx.var.file;
local index = last_find(ngx.var.uri, "([0-9]+)x([0-9]+)");  
if index then 
    originalUri = string.sub(ngx.var.uri, 0, index-2);  
    area = string.sub(ngx.var.uri, index);  
    index = string.find(area, "([.])");  
    area = string.sub(area, 0, index-1);  

    local index = last_find(originalFile, "([0-9]+)x([0-9]+)");  
    originalFile = string.sub(originalFile, 0, index-2)
end

-- check original file
if not file_exists(originalFile) then
    local fileid = string.sub(originalUri, 2);
    -- main
    local fastdfs = require('restyfastdfs')
    local fdfs = fastdfs:new()
    fdfs:set_tracker("10.1.8.43", 22122)
    fdfs:set_tracker("10.1.8.44", 22122)
    fdfs:set_timeout(1000)
    fdfs:set_tracker_keepalive(0, 100)
    fdfs:set_storage_keepalive(0, 100)
    local data = fdfs:do_download(fileid)
    if data then
       -- check image dir
        if not is_dir(ngx.var.image_dir) then
            os.execute("mkdir -p " .. ngx.var.image_dir)
        end
        writefile(originalFile, data)
    end
end

-- 创建缩略图
-- local image_sizes = {"50x50", "100x100", "400x400", "640x320","600x600","240x150","300x300","90x90","130x130","150x150","180x180","230x230","270x270"};
local image_sizes = {"50x50","100x100", "150x150", "200x200", "300x300", "400x400","600x600","800x800"};
function table.contains(table, element)  
    for _, value in pairs(table) do  
        if value == element then
            return true  
        end  
    end  
    return false  
end 

if table.contains(image_sizes, area) then  
    local bg;
    if string.lower(string.sub(ngx.var.file,-3))=="jpg" then
        bg=" -background white ";
    else
        bg=" -background transparent ";
    end;
    local command = "/usr/local/GraphicsMagick/bin/gm convert -quality 90 " .. originalFile  .. " -thumbnail " .. area .. bg .. " -gravity center -extent " .. area .. " " .. ngx.var.file;  
    os.execute(command);  
end;

if file_exists(ngx.var.file) then
    --ngx.req.set_uri(ngx.var.uri, true);  
    ngx.exec(ngx.var.uri)
else
    ngx.exit(404)
end

 

b.配置nginx文件

#
server {
        listen 8801;
        server_name 10.160.43.26;

        # LUA
        location /hello {
                default_type 'text/plain';
                content_by_lua 'ngx.say("hello,lua")';
                }

        # fastdfs 缩略图生成
        location /group1/M00 {
                alias /data/fastdfs/data/data;

                set $image_root "/data/fastdfs/data/data";
                if ($uri ~ "/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/(.*)") {
                  set $image_dir "$image_root/$3/$4/";
                  set $image_name "$5";
                  set $file "$image_dir$image_name";
                }

                if (!-f $file) {
        #         # 关闭lua代码缓存,方便调试lua脚本
                  #lua_code_cache off;
                  content_by_lua_file "/usr/local/nginx/conf/lua/fastdfs.lua";
                }
                ngx_fastdfs_module;
        }

        # log file
        access_log  logs/img_access.log access;
}

   c.图片目录赋予网站用户写的权限

/data/fastdfs/data
chown -R nginx.nginx data
/usr/local/nginx/sbin/nginx -t
/usr/local/nginx/sbin/nginx -s reload

   d.测试文件

 原图

 

 

参考文档:http://ylw6006.blog.51cto.com/470441/1830002

              https://github.com/hpxl/nginx-lua-fastdfs-GraphicsMagick

posted @ 2016-12-21 16:31  sunmmi  阅读(1545)  评论(0)    收藏  举报