使用nginx+Lua+GraphicsMagick實現圖片自動裁剪

在作網站尤爲是之內容爲主的過程當中,經常會遇到一張圖片各類地方都要引用,且每一個引用的地方要求的圖片尺寸都不同的。對於小網站來講,這種需求一般是人工進行裁剪,而後在代碼上分別引用。然而當網站圖片愈來愈多的時候,這種辦法的效率問題就凸顯出來了,因此通常中大型的網站都會對這一類的圖片作自動裁剪功能。本文介紹在centos6操做系統上,採用nginxluaGraphicsMagick工具簡單實現圖片的自動裁剪功能。其中nginx負責展現圖片和調度lua腳本,GraphicsMagick負責對原圖進行裁剪。html

實現功能點以下:linux

一、輸入原圖地址,例如:http://192.168.1.19/img_6065.jpg後返回原圖nginx

二、輸入圖片地址,例如:http://192.168.1.19/img_6065.jpg_200x400.jpg 後,若是目錄底下存在圖片,則返回,若是不存在則根據需求對原圖進行裁剪,其中200表明圖片的寬,400表明圖片的長。c++

三、圖片的根目錄爲/static/p_w_picpaths,裁剪後的圖片和原圖放在同一級目錄,例如原圖地址的物理路徑爲:/static/p_w_picpaths/uploads/2016/07/01.jpg git

200x200裁剪後的圖片物理路徑爲:/static/p_w_picpaths/uploads/2016/07/01_200x200.jpggithub

 

1、基礎軟件包安裝centos

# groupadd www
# useradd -g www www -s /bin/false
# yum -y install epel-release git
# yum install -y gcc gcc-c++ zlib zlib-devel openssl openssl-devel pcre pcre-devel
# yum install -y libpng libjpeg libpng-devel libjpeg-devel ghostscript libtiff libtiff-devel freetype freetype-devel readline-devel ncurses-devel

2、下載相關軟件緩存

其中nginx-http-concatecho-nginx-module模塊非必須app

# cd /usr/local/src
# wget http://nginx.org/download/nginx-1.8.0.tar.gz
# wget http://luajit.org/download/LuaJIT-2.0.4.tar.gz
# wget http://zlib.net/zlib-1.2.8.tar.gz
# wget http://www.lua.org/ftp/lua-5.3.1.tar.gz  
# wget ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/1.3/GraphicsMagick-1.3.18.tar.gz
 
# 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

3、編譯安裝nginx、GraphicsMagicktcp

# tar -zxf nginx-1.8.0.tar.gz
# tar -zxf LuaJIT-2.0.4.tar.gz
# tar -zxf zlib-1.2.8.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
 
# cd ..
# tar -zxvpf lua-5.3.1.tar.gz
# cd lua-5.3.1
# make linux && make install
 
# cd ..
# tar -zxvpf GraphicsMagick-1.3.18.tar.gz
# cd GraphicsMagick-1.3.18
# ./configure --prefix=/usr/local/GraphicsMagick --enable-shared
# make  && make install
 
# cd ..
# cd nginx-1.8.0
# ./configure --prefix=/usr/local/nginx \
--user=www \
--group=www \
--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 \
--with-http_spdy_module \
--with-pcre \
--with-zlib=../zlib-1.2.8 \
--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

4、修改nginx配置文件

   server {
        listen       80;
        server_name  192.168.1.19;
        root /static/p_w_picpath;
 
        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 /static/p_w_picpath;
                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 /static/p_w_picpath/$1;    # 設置原始圖片路徑,如:/document_root/1.gif
                        set $width $3;    # 設置裁剪/縮放的寬度
                        set $height $4;    # 設置裁剪/縮放的高度
                        set $ext $5;    # 圖片文件格式後綴
                        content_by_lua_file lua/ImageResizer.lua;    # 加載外部 Lua 文件
                }
 
 
        }
}

5、準備lua腳本

# cat /usr/local/nginx/lua/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);

6、測試

# cd /static/p_w_picpath/
# ls
# cd uploads/2016/07/21/
# ls

wKioL1eWyGmhp2LOAABrtKx0wvQ028.jpg-wh_50

wKiom1eWyGmRGVmZAAFLZJb2QrY830.jpg-wh_50

wKioL1eWyGzCIgluAAVldYxJx-A921.png-wh_50

wKiom1eWyG2w6PdcAAHwyhW-1yI343.png-wh_50

wKiom1eWyG2jCNXPAAFHDnbl9jI722.png-wh_50

wKioL1eWyG7zoWTlAACWV4Z7H7A678.jpg-wh_50

若是要作固定高寬模式裁切圖片處理,例如:http://192.168.1.19/uploads/2016/07/21/1.jpg_-200.jpg 或http://192.168.1.19/uploads/2016/07/21/1.jpg_200-.jpg 這種需求,首先修改nginx配置文件以下

http {
    include       mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  logs/access.log  main;
    sendfile        on;
    tcp_nopush     on;
    keepalive_timeout  65;
    gzip  on;

    server {
        listen       80;
        server_name  192.168.1.19;
        root /static/p_w_picpath;

        location /lua1 {
        default_type 'text/plain';
        content_by_lua 'ngx.say("hello, lua")';
        }
   set $upload_path /static/p_w_picpath;
    set $img_original_root  $upload_path;# original root;
    set $img_thumbnail_root $upload_path/cache/thumb;
    set $img_file $img_thumbnail_root$uri;

    # like:/xx/xx/xx.jpg_100-.jpg or /xx/xx/xx.jpg_-100.jpg
    location ~* ^(.+\.(jpg|jpeg|gif|png))_((\d+\-)|(\-\d+))\.(jpg|jpeg|gif|png)$ {
            root $img_thumbnail_root;    # root path for croped img
            set $img_size $3;

            if (!-f $img_file) {    # if file not exists
                    add_header X-Powered-By 'Nginx+Lua+GraphicsMagick By Yanue';  #  header for test
                    add_header file-path $request_filename;    #  header for test
                    set $request_filepath $img_original_root$1;    # origin_img full path:/document_root/1.gif
                    set $img_size $3;    # img width or height size depends on uri
                    set $img_ext $2;    # file ext
                    content_by_lua_file lua/autoSize.lua;    # load lua
            }
    }

    # like: /xx/xx/xx.jpg_100x100.jpg
    location ~* ^(.+\.(jpg|jpeg|gif|png))_(\d+)+x(\d+)+\.(jpg|jpeg|gif|png)$ {
            root $img_thumbnail_root;    # root path for croped img

            if (!-f $img_file) {    # if file not exists
                    add_header X-Powered-By 'Nginx+Lua+GraphicsMagick By Yanue';  #  header for test
                    add_header file-path $request_filename;    #  header for test
                    set $request_filepath $img_original_root$1;    # origin_img file path
                    set $img_width $3;    # img width
                    set $img_height $4;    # height
                    set $img_ext $5;    # file ext
                    content_by_lua_file lua/cropSize.lua;    # load lua
            }
    }

}

}

其次準備兩個lua腳本,腳本包含在附件中。

測試效果以下:

wKiom1eXMc3S7kHBAACNxiClap4879.jpg-wh_50

wKioL1eXMc7wV8g2AACGH8po2sc829.jpg-wh_50

wKiom1eXMc-w83YjAABdJN_Ef1o807.jpg-wh_50


後記:

採用這種方式簡單實現了需求,可是url中的圖片高度和寬度沒有限制,這個須要注意,還有長時間不用的縮略圖如何清理也須要考慮。

 

參考文檔,感謝做者分享!

http://my.oschina.net/eduosi/blog/169606

http://blog.ddtet.org/2014/03/graphicsmagick.html

https://github.com/yanue/nginx-lua-GraphicsMagick

http://www.111cn.net/sys/CentOS/55070.htm

相關文章
相關標籤/搜索