您的位置:首页 > 编程语言 > Lua

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

2017-09-12 17:44 435 查看

1.产生的背景

随着互联网的快速发展、需求频繁变更、内容数量的俱增、时间的持续增长,图片数量也会越来越多。在实际需求中,会出现在若干个页面或同一个页面不同位置,展示同一条信息以及其缩略图。在这时,如果使用 CSS 控制图片显示的大小,对于那些与该位置不成比例的图片,缩小后就会出现图片变形。也不可能让编辑人员,对所有的图片进行 PS,这时候就产生了强烈的自动化裁剪、缩放图片的需求,来适应不同规格的缩略图。

Nginx 虽然有自带的 image filter module 也能实现此功能,但是有弊端:

image filter module 使用的是 GD,GD 性能、效率、处理后的图片质量不如 GraphicsMagick

image filter module 没法真正生成裁剪/缩放后的图片,而是通过 Nginx 直接输出的,这样每次请求或缓存过期后都需要重新裁剪/缩放,这样无疑会增加 Nginx 负担

2.准备安装的软件

操作系统是:centos7 linux

Tengine:https://github.com/alibaba/tengine

详细过程如图:







Lua:http://www.lua.org/download.html



LuaJIT:http://luajit.org/download.html



所需的依赖包:

libjpeg、libjpeg-devel

libpng、libpng-devel

giflib、giflib-devel

freetype、freetype-devel

GraphicsMagick:http://sourceforge.net/projects/graphicsmagick/files/graphicsmagick/





3.安装软件

3.1Lua的安装

注意:readline&readline-devel(Lua 所需)

# yum install readline
# yum install readline-devel


详细的安装步骤,请参考: centos7下安装lua-5.3.4

3.2LuaJIT的安装

下载、解压、编译

$ wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz $ tar -xzf LuaJIT-2.0.5.tar.gz
//切换到root用户下执行编译
# make && make install


出现如图所示,证明成功:



3.3Tengine的安装

解压、安装命令如下:

$ wget http://tengine.taobao.org/download/tengine-2.2.0.tar.gz $  tar -xzf tengine-2.2.0.tar.gz


进入 Tengine 源码目录

$ cd tengine-2.2.0

$ ./configure --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




切换到root用户,执行编译

# make && make install




如果报有下面错误:

src/http/modules/lua/ngx_http_lua_log.c: 在函数‘ngx_http_lua_ngx_log’中:
src/http/modules/lua/ngx_http_lua_log.c:40: 错误:‘LUA_GLOBALSINDEX’未声明(在此函数内第一次使用)
<
f068
span class="hljs-attribute">src/http/modules/lua/ngx_http_lua_log.c:40: 错误:(即使在一个函数内多次出现,每个未声明的标识符在其
src/http/modules/lua/ngx_http_lua_log.c:40: 错误:所在的函数内也只报告一次。)
src/http/modules/lua/ngx_http_lua_log.c: 在函数‘ngx_http_lua_print’中:
src/http/modules/lua/ngx_http_lua_log.c:81: 错误:‘LUA_GLOBALSINDEX’未声明(在此函数内第一次使用)


时,是因为使用了不兼容的 Lua 的头文件,configure 需要加上

--with-ld-opt="-Wl,-rpath,$LUAJIT_LIB"


或者

--with-luajit-inc=PATH             set LuaJIT headers path (where lua.h/lauxlib.h/... are located)
--with-luajit-lib=PATH             set LuaJIT library path (where libluajit-5.1.{a,so} are located)


如果在启动或者执行 Tengine 任意命令时,出现以下错误,那么就是,无法找到动态库 libluajit-5.1.so.2 ,64位系统貌似是去 /lib64 目录中寻找动态库的。



那么解决办法就是,将 /usr/local/lib/libluajit-5.1.so.2 软连接到 /lib64 目录下:

ln -s /usr/local/lib/libluajit-5.1.so.2 /lib64/libluajit-5.1.so.2


3.4安装依赖

yum -y install libjpeg libjpeg-devel libpng libpng-devel giflib giflib-devel freetype freetype-devel


3.5GraphicsMagick的安装

下载、解压

$ wget https://sourceforge.net/projects/graphicsmagick/files/graphicsmagick/1.3.26/GraphicsMagick-1.3.26.tar.gz/download $ tar -xzf GraphicsMagick-1.3.26.tar.gz


进入 Tengine 源码目录,指定安装路径

$ cd GraphicsMagick-1.3.26
$ ./configure --prefix=/usr/local/gm --enable-shared


切换到root用户编译安装

# make && make install


在root用户下执行:
cd /usr/local/gm/bin/
执行

# ./gm version


看到如下图所示,证明安装成功



4. 修改tengine配置文件

在root用户下执行:

# cd /usr/local/tengine/conf/
# cp nginx.conf nginx.conf.bak
# cd nginx.conf


修改nginx.conf文件

#user  nobody;
user 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  localhost;

#charset koi8-r;

#access_log  logs/host.access.log  main;

location / {
root   /home/hadoop/images;
index  index.html index.htm;
}
location /lua/ {
default_type 'text/html';
content_by_lua 'ngx.say("<h1>hello, ttlsa lua</h1>")';
}
location ~* ^(.+\.(jpg|jpeg|gif|png))_(\d+)x(\d+)\.(jpg|jpeg|gif|png)$ {
root /home/hadoop/images;
if (!-f $request_filename) {
lua_code_cache off;
set $request_filepath /home/hadoop/images/$1;
set $width $3;
set $height $4;
set $ext $5;
content_by_lua_file /usr/local/tengine/lua/ImageResizer.lua;
}
}

#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;
#    }
#}

}


修改之处如下图所示:





5.编译脚本

在root用户下,执行

# cd /usr/local/tengine/
# mkdir lua
# cd lua/
# vi ImageResizer.lua


在ImageResizer.lua文件里添加

local command = "/usr/local/gm/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);




6.测试脚本

# cd /usr/local/tengine/sbin/
# ./nginx


第一次启动会出现,如下的错误:

nginx: [emerg] mkdir() "/var/tmp/Tengine/client_body_temp" failed (2: No such file or directory)




解决的办法:

# mkdir -p /var/tmp/Tengine/client_body_temp


筛选当前正在执行nginx的进程:
ps -aux | grep nginx


# ./nginx -t    #查看编译是否成功
# ./nginx -s reload  #重启nginx


在WEB浏览器上输入自己的IP+你图片的名字,效果如下:



设置自己图片的大小后的效果:



笔者推荐链接:

http://blog.csdn.net/xiaolang85/article/details/41675315

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

http://www.ttlsa.com/nginx/nginx-modules-ngx_lua/

https://my.oschina.net/eduosi/blog/169606
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  lua tengine