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

发布于:25-07-01 播放次数:

[id_[id_1095210196]972565091]

互联网的迅猛进步、需求的不断变动、内容量的显著提升以及时间的不断延伸,都使得图片的数量持续攀升。在具体应用场景中,我们常常会在多个页面或同一页面的不同区域看到相同的信息及其缩略图。在这种情况下,若通过 CSS 来调整图片的显示尺寸kaiyun.ccmkaiyun全站网页版登录,对于那些与所处位置不协调的图片,一旦缩小,便容易出现图片失真的现象。编辑人员无法对每一张图片都进行PS处理,因此迫切需要一种自动化的裁剪和缩放功能,以便生成符合不同尺寸要求的缩略图。

Nginx 确实内置了图像过滤器模块,能够完成这项任务,然而它存在一些不足之处:

图像处理模块采用的是GD库,然而GD在性能、效率以及处理后的图片质量方面均不及GraphicsMagick。

图像处理模块无法直接生成经过裁剪或缩放的图片,它实际上是通过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

[id_649335029]

giflib、giflib-devel

freetype、freetype-devel

GraphicsMagick项目位于:http://sourceforge.net/projects/graphicsmagick/files/graphicsmagick/,该链接提供了相关资源的下载。

这里写图片描述

这里写图片描述

3.安装软件 3.1Lua的安装

请注意:Lua依赖的readline及其开发包(readline-devel)不得修改。

[id_400100504]
# yum install readline-devel

请查阅以下详细安装指南:在CentOS 7系统中进行lua-5.3.4的安装。

3.2LuaJIT的安装

下载、解压、编译

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

[id_909105003]

这里写图片描述

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模块中的lua子系统,具体到ngx_http_lua_log.c文件,对其进行了规定。: 在函数‘ngx_http_lua_ngx_log’中:
src/http模块下的lua子模块中的ngx_http_lua_log源文件,位于第40行。: 在当前函数执行过程中,遇到了未声明的变量,具体是名为'LUA_GLOBALSINDEX'的标识符,这是它在该函数中的首次被引用。
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模块下的lua子模块中的ngx_http_lua_log源文件,位于第81行。: 错误:‘LUA_GLOBALSINDEX’未声明(在此函数内第一次使用)

在此时,原因在于配置过程中采用了与 Lua 不相容的头文件,因此,configure 命令的执行需要添加特定的参数。

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

或者

使用-luajit-inc=PATH选项,指定LuaJIT头文件路径(即包含lua.h、lauxlib.h等文件的目录)。... are located)
使用指定路径设置LuaJIT库,命令格式为--with-luajit-lib=PATH。library path (where libluajit-5.1.{a,so} are located)

在启动或运行Tengine的任何指令过程中,若遭遇下列错误,这表明系统未能找到名为libluajit-5.1.so.2的动态库。在64位系统上开yun体育app官网网页登录入口,似乎该动态库被定位在/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/
执行命令以备份配置文件nginx.conf,并将其重命名为nginx.conf.bak。
# cd nginx.conf

修改nginx.conf文件


#user  nobody;
user root;
worker_processes  1;
#error_log  logs/error.log;
错误日志记录于路径为logs/error.log的文件中,并标记为注意级别。
错误日志记录于路径为logs目录下的error.log文件中,并包含信息内容。
#pid        logs/nginx.pid;
events {
    worker_connections  1024;
}
加载编译成动态共享对象(DSO)的模块
#
#dso {

加载ngx_http_rewrite_module模块的共享对象文件。
#}
http {
    include       mime.types;
    default_type  application/octet-stream;
    日志格式主要设置为:记录远程地址、用户信息、本地时间以及请求内容,格式如下:$remote_addr - $remote_user [$time_local] "$request" 。
    禁止对内容进行修改,确保发送的字节数符合规定,记录下引用来源的URL,并以此信息作为记录。
    禁止对“http_user_agent”和“http_x_forwarded_for”进行修改;
    配置访问日志,将其记录至“logs/access.log”文件,并设置主要模式。
    sendfile        on;
    #tcp_nopush     on;
    #keepalive_timeout  0;
    keepalive_timeout  65;
    #gzip  on;
    server {
        listen       80;
        server_name  localhost;
        #charset koi8-r;
        配置访问日志,指定输出至“logs/host.access.log”文件,并设置为默认模式。
        location / {
            root   /home/hadoop/images;
            index  index.html index.htm;
        }
        location /lua/ {
            default_type 'text/html';
            content_by_lua 'ngx.say("

hello, ttlsa lua

")'
; } 限制访问特定格式图片,条件为文件名包含.jpg、.jpeg、.gif或.png后缀,且格式为“图片名_宽x高.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。 } } 错误页面设置为404,访问路径指向404.html文件。 将服务器错误页面重定向至静态页面/50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } 将PHP脚本代理至监听在127.0.0.1端口80的Apache服务器上。 # #location ~ \.php$ { 设置代理服务器地址为本地网络地址,即http://127.0.0.1; #} 将PHP脚本传递给监听于127.0.0.1地址的9000端口的FastCGI服务器。 # #location ~ \.php$ { # root html; 配置文件中指定了FastCGI的进程通过本地回环地址127.0.0.1上的端口9000进行通信。 禁止使用index.php作为默认首页文件; 设置fastcgi参数,将脚本文件名指定为/script目录下的$fastcgi_script_name变量所对应的值。 引入fastcgi参数配置文件。 #} 若Apache的文档根目录设置不允许,则应拒绝访问.htaccess文件。 该观点与nginx的立场相一致。 # #location ~ /\.ht { # deny all; #} } 设立另一个虚拟主机,采用结合IP地址、域名和端口号的配置方式。 # #server { # listen 8000; 监听指定地址,端口号为8080,用户名为somename。 服务器名称设定为somename,同时别名设置为another.alias,两者以分号隔开。 # location / { # root html; 禁止对以下文件进行修改:index、index.html、index.htm。 # } #} # HTTPS server # #server { # listen 443 ssl; # server_name localhost; 禁止使用专有证书文件,须确保采用cert.pem文件进行认证。 配置SSL证书的私钥文件为cert.key。 禁止设置专有缓存参数,应采用共享模式,指定SSL类型,并设定缓存大小为1兆字节。 # ssl_session_timeout 5m; SSL加密方式设定为:高安全级别,排除aNULL和MD5算法。 启用服务器优先使用加密密钥;确保SSL连接中优先采用服务器端提供的加密算法。 # 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)

解决的办法:

创建目录 /var/tmp/Tengine/client_body_temp,确保其存在,并使用 mkdir -p 命令执行此操作。

查询当前运行中的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