Tengine+Lua+GraphicsMagick实现图片自动裁剪缩放

图片处理需求

  • 问题
    • 互联网电商网站(PC端,移动端)
    • 大量不同需求的图片(同一个图片需要不同尺寸的缩略图)
  • 解决方案
    • 两种策略生成缩略图
      • 在上传图片时,就生成所需缩略图
    • 根据请求指定尺寸的图片自动生成响应的缩略图片
      • Tengine+Lua+GraphicsMagick

技术介绍

  • Tengine
    • 淘宝优化改良的nginx,并集成了lua模块
    • 负责展示图片和调度Lua脚本
  1. gine是由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。它的目的是打造一个高效、安全的Web平台。
  • Lua
    • 脚本语言,嵌入到应用程序中,提供灵活的扩展和定制功能
    • Tengine通过lua实现对GM的操作
    • 控制裁剪,缩放规格
  1. [1] 是一个小巧的脚本语言。是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组,由Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo所组成并于1993年开发。 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。由标准C编写而成,几乎在所有操作系统和平台上都可以编译,运行。并没有提供强大的库,这是由它的定位决定的。所以不适合作为开发独立应用程序的语言。 有一个同时进行的JIT项目,提供在特定平台上的即时编译功能。
  2. 脚本可以很容易的被C/C++ 代码调用,也可以反过来调用C/C++的函数,这使得在应用程序中可以被广泛应用。不仅仅作为扩展脚本,也可以作为普通的配置文件,代替XML,ini等文件格式,并且更容易理解和维护。 [2] 由标准C编写而成,代码简洁优美,几乎在所有操作系统和平台上都可以编译,运行。 [2] 一个完整的解释器不过200k,在目前所有脚本引擎中,的速度是最快的。这一切都决定了是作为嵌入式脚本的最佳选择。 [2]
  • GraphicsMagick
    • 强大的图片处理工具,没有UI的PS,动态的生成图片,特别适用于互联网的应用
    • 负责图片处理
  1. 号称图像处理领域的瑞士军刀。 短小精悍的代码却提供了一个鲁棒、高效的工具和库集合,来处理图像的读取、写入和操作,支持超过88种图像格式,包括重要的DPX、GIF、JPEG、JPEG-2000、PNG、PDF、PNM和TIFF。
  • 原理图

Tengine+Lua+GraphicsMagick实现图片自动裁剪缩放_第1张图片

 

安装配置

  • 软件列表
    • Tengine
      • 安装包:tengine-master.zip
      • 下载地址
        • https://github.com/alibaba/tengine
    • Lua
      • lua-5.3.1.tar.gzLuaJIT-2.0.4.tar.gz(Lua依赖包)
      • 下载地址
        • http://www.lua.org/ftp/
        • http://luajit.org/download.html
    • GraphicsMagick
      • GraphicsMagick-1.3.18.tar.gz
      • 下载地址
        • https://sourceforge.net/projects/graphicsmagick/files/graphicsmagick/
    • 依赖包和类库,可以使用yum安装
      • libjpeg、libjpeg-devel
      • libpng、libpng-devel
      • giflib、giflib-devel
      • freetype、freetype-devel

安装

  • Lua
    • 安装依赖(readline&readline-devel)
      • yum install readline
      • yum install readline-devel
    • 安装Lua(源码编译安装)
      • cd lua-5.3.1
      • make linux(需要指定操作系统否则会报错)
      • make install
    • 安装LuaJIT (源码编译安装)
      • cd LuaJIT-2.0.4
      • make && make install
    • 检测是否安装成功
      • lua -v

 

  • Tengine
    • 进入Tengine源码目录,使用configure配置安装路径以及需要安装的模块
      • unzip tengine-master.zip
      • cd tengine-master
      • yum -y install openssl openssl-devel
    1. --prefix=/usr/local/Tengine --dso-path=/usr/local/Tengine/modules --with-http_realip_module --with-http_gzip_static_module --with-http_stub_status_module --with-http_concat_module --with-http_lua_module  --http-proxy-temp-path=/var/tmp/Tengine/proxy_temp --http-fastcgi-temp-path=/var/tmp/Tengine/fastcgi_temp --http-uwsgi-temp-path=/var/tmp/Tengine/uwsgi_temp --http-scgi-temp-path=/var/tmp/Tengine/cgi_temp --http-client-body-temp-path=/var/tmp/Tengine/client_body_temp --http-log-path=/var/log/Tengine/access.log --error-log-path=/var/log/Tengine/error.log
    • 安装Tengine (源码编译安装)
      • make && make install
    • 启动
      • /usr/local/Tengine/sbin/nginx
      • 启动报错

      • ln -s /usr/local/lib/libluajit-5.1.so.2 /lib64/libluajit-5.1.so.2
      • 文件夹找不到

      • mkdir -p /var/tmp/Tengine/clientbodytemp
    • 成功页面

Tengine+Lua+GraphicsMagick实现图片自动裁剪缩放_第2张图片

  • GraphicsMagick
    • 安装依赖(通过yum命令在线安装)
      • llibjpeg & libjpeg-devel
      • libpng & libpng-devel
      • giflib & giflib-devel
      • freetype & freetype-devel
      • yum命令
        • yum -y install llibjpeg libjpeg-devel libpng libpng-devel giflib giflib-devel freetype freetype-devel
    • 进入GM源码目录,使用configure配置安装路径以及需要安装的模块
      • cd GraphicsMagick-1.3.18
      • ./configure --prefix=/usr/local/GraphicsMagick --enable-shared
    • 安装GM(源码编译安装)
      • make && make install
    • 验证是否安装成功
      • /usr/local/GraphicsMagick/bin/gm version

配置

  • Lua脚本文件(ImageResizer.lua)
    • 位置:/usr/local/Tengine/lua/ImageResizer.lua
    • 权限:可执行
    • chmod a+x /usr/local/Tengine/lua/ImageResizer.lua
  1. command = "/usr/local/GraphicsMagick/bin/gm convert " .. 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);
  • Tengine配置(nginx.conf)
  1.   nobody;
    user  root;  # 裁剪图片需要root权限
    worker_processes  1;
     
    #error_log  logs/error.log;
    #error_log  logs/error.log  notice;
    #error_log  logs/error.log  info;
     
    #pid        logs/nginx.pid;
     
     
    events {
        worker_connections  1024;
    }
     
    # load modules compiled as Dynamic Shared Object (DSO)
    #
    #dso {
    #    load ngx_http_fastcgi_module.so;
    #    load ngx_http_rewrite_module.so;
    #}
     
    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  0;
        keepalive_timeout  65;
     
        #gzip  on;
     
        server {
            listen       80;
            server_name  img.itrip.project.bdqn.cn;
            root /data/itrip/uploadimg;
     
            location / {
                 root /data/itrip/uploadimg; # 站点根目录
                 expires 1h;    # 缓存时间
                 add_header Cache-Control max-age=3600; # 缓存时间
                 access_log   /var/log/Tengine/host_access.log;
            }
     
            # 如果 url 格式如:xxxx.gif_数字x数字.gif
            location ~* ^(.+\.(jpg|jpeg|gif|png))_(\d+)x(\d+)\.(jpg|jpeg|gif|png)$ {
            # 这里必须设置,否则根目录,即 $document_root 会是 Nginx 默认的 Nginx Root/html,在Lua中会得不到期望的值   
                root /data/itrip/uploadimg;
     
                if (!-f $request_filename) { # 如果文件不存在时才需要裁剪
                    add_header X-Powered-By 'Lua GraphicsMagick';  # 此HTTP Header无实际意义,用于测试
                    add_header file-path $request_filename;  #此HTTP Header无实际意义,用于测试
                    lua_code_cache on;  # 在编写外部 Lua脚本时,设置为off Nginx不会缓存 Lua,方便调试
                    set $request_filepath /data/itrip/uploadimg$1;  #设置原始图片路径,如:/document_root/1.gif
                    set $width $3;     # 设置裁剪/缩放的宽度
                    set $height $4;    # 设置裁剪/缩放的高度
                    set $ext $5;      # 图片文件格式后缀
                    content_by_lua_file /usr/local/Tengine/lua/ImageResizer.lua;  # 加载外部 Lua 文件
                }
            }
     
     
            #charset koi8-r;
     
            #access_log  logs/host.access.log  main;
     
            #location / {
            #    root   html;
            #    index  index.html index.htm;
            #}
     
     
     
            #error_page  404              /404.html;
     
            # redirect server error pages to the static page /50x.html
            #
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
     
            # proxy the PHP scripts to Apache listening on 127.0.0.1:80
            #
            #location ~ \.php$ {
            #    proxy_pass   http://127.0.0.1;
            #}
     
            # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
            #
            #location ~ \.php$ {
            #    root           html;
            #    fastcgi_pass   127.0.0.1:9000;
            #    fastcgi_index  index.php;
            #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            #    include        fastcgi_params;
            #}
     
            # deny access to .htaccess files, if Apache's document root
            # concurs with nginx's one
            #
            #location ~ /\.ht {
            #    deny  all;
            #}
        }
     
     
        # another virtual host using mix of IP-, name-, and port-based configuration
        #
        #server {
        #    listen       8000;
        #    listen       somename:8080;
        #    server_name  somename  alias  another.alias;
     
        #    location / {
        #        root   html;
        #        index  index.html index.htm;
        #    }
        #}
     
     
        # HTTPS server
        #
        #server {
        #    listen       443 ssl;
        #    server_name  localhost;
     
        #    ssl_certificate      cert.pem;
        #    ssl_certificate_key  cert.key;
     
        #    ssl_session_cache    shared:SSL:1m;
        #    ssl_session_timeout  5m;
     
        #    ssl_ciphers  HIGH:!aNULL:!MD5;
        #    ssl_prefer_server_ciphers  on;
     
        #    location / {
        #        root   html;
        #        index  index.html index.htm;
        #    }
        #}
     
    }

你可能感兴趣的:(Linux)