OpenResty(Nginx)+Lua+GraphicsMagick实现缩略图功能
一、背景说明
大多数网站基本都涉及到图片缩略图的处理,比如新闻配图、电商商品图等,特别是电商类网站,每个商品图对应多个不同尺寸的缩略图,用于不同的页面。
初期访问量少时,处理流程一般由web程序在上传成功后,同时生成相应缩略图。这种方式在访问量小,单机部署时没有问题。当访问量逐渐加大,服务器由单台变为多台时,这种方式扩展性较差。
以下有几种方案可以解决这个问题:
1、使用七牛、又拍云提供的云存储及数据处理服务,解决图片的处理、存储、多节点访问速度的问题,这种方式优点是方案成熟,相应的有一定费用和开发工作,另外有一些小概率的风险,比如云服务挂掉影响本站访问。
2、使用第三方的图片处理程序,比如zimg,点击查看使用手册,@招牌疯子开发。zimg的性能和扩展性不错,文档也很完善,会继续保持关注。
3、自己造轮子,根据自身业务,将生成缩略图功能独立出来,与web程序解耦。
我们采用的是第三种方案,参考了网友的基础代码,利用OpenResty(Nginx)+Lua+GraphicsMagick实现缩略图功能,图片上传及删除还是由web程序处理,缩略图由单独模块完成。目前可实现配置路径及缩略尺寸,无图片时显示默认图片,支持多种缩放方式等,后续可基于GraphicsMagick实现更多功能
二、相关规范
1、文件夹规划
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
img.hopesoft.org
|-- avatars
| `-- 001
| `-- 001.jpg
|-- default
| `-- notfound.jpg
|-- photos
| `-- 001
| `-- 001.jpg
`-- thumbnail
`-- photos
`-- 001
|-- 001_100x100.jpg
|-- 001_140x140.jpg
|-- 001_250x250.jpg
|-- 001_300x300.jpg
|-- 001_350x350.jpg
|-- 001_50x50.jpg
`-- abc_50x50.jpg
|
其中img.hopesoft.org为图片站点根目录,avatars和photos目录是原图目录,可根据目录设置不同的缩略图尺寸,default文件夹的notfound.jpg文件是在未找到原图时的默认图片,thumbnail文件夹用来存放缩略图,可定时清理。
2、链接地址
原图访问地址:http://img.hopesoft.org/photos/001/001.jpg
缩略图访问地址:http://img.hopesoft.org/photos/001/001_100x100.jpg,(请勿加thumbnail,这个是因为我们原来的原图和缩略图在同一个目录,后来将缩略图单独放了一个文件夹)
不同目录可设置不同的缩略图规则,如:
原图访问地址:http://img.xxx.com/mall/001/001.jpg
缩略图访问地址:http://img.xxx.com/mall/001/001.jpg_100x100.jpg (请勿加thumbnail)
3、访问流程
首先判断缩略图是否存在,如存在则直接显示缩略图;
如不存在则按以下流程处理:
- 判断缩略图链接与规则是否匹配,如不匹配,则404退出;如匹配跳至2
- 判断原图是否存在,如原图存在则跳至5,如不存在则进入下一步;
- 判断是否显示默认图片,如不显示则404退出;如显示则进入下一步
- 判断是否存在默认图片,如不存在则404退出;如存在则将默认图片代替原始图片,进入下一步;
- 拼接graphicsmagick命令,生成并显示缩略图
三、安装OpenResty
1、关于OpenResty(http://openresty.org/cn/)
OpenResty (也称为 ngx_openresty)是一个全功能的 Web 应用服务器,它打包了标准的 Nginx 核心,很多的常用的第三方模块,以及它们的大多数依赖项。
OpenResty 通过汇聚各种设计精良的 Nginx 模块,
从而将 Nginx 有效的变成一个强大的 Web 应用服务器,
这样, Web 开发人员可以使用 Lua 脚本语言调动 Nginx 支持的各种C以及Lua 模块,
快速构造出足以胜任 10K+ 并发连接响应的超高性能Web 应用系统。更多
2、安装OpenResty
注:drizzle-nginx-module模块和nginx-http-concat模块非必选项,各位可按需安装
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
#创建安装文件目录
mkdir -p /usr/local/src/nginx
cd /usr/local/src/nginx
#安装drizzle模块(访问mysql数据库模块,非必需,建议安装)
wget http://agentzh.org/misc/nginx/drizzle7-2011.07.21.tar.gz
tar zxvf drizzle7-2011.07.21.tar.gz
cd drizzle7-2011.07.21
./configure --without-server
make libdrizzle-1.0
make install-libdrizzle-1.0
cd ..
#下载openresty
wget http://openresty.org/download/ngx_openresty-1.4.2.7.tar.gz
tar zxvf ngx_openresty-1.4.2.7.tar.gz
#下载nginx-http-concat(合并静态文件请求模块,非必需,建议安装)
wget https://github.com/alibaba/nginx-http-concat/archive/master.zip
unzip master
mv nginx-http-concat-master/ ngx_openresty-1.4.2.7/bundle/nginx-http-concat
#安装openresty
cd ngx_openresty-1.4.2.7
./configure --with-luajit --with-http_drizzle_module --with-http_iconv_module --with-ld-opt="-Wl,-rpath,/usr/local/lib" --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --add-module=./bundle/nginx-http-concat/
gmake
gmake install
|
3、将OpenResty(Nginx)加入自启动
1
|
vi /etc/rc.d/init.d/nginx
|
文件内容如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
#! /bin/sh
# chkconfig: 2345 55 25
# Description: Startup script for nginx webserver on Debian. Place in /etc/init.d and
# run 'update-rc.d -f nginx defaults', or use the appropriate command on your
# distro. For CentOS/Redhat run: 'chkconfig --add nginx'
### BEGIN INIT INFO
# Provides: nginx
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts the nginx web server
# Description: starts nginx using start-stop-daemon
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="nginx daemon"
NAME=nginx
DAEMON=/usr/local/openresty/nginx/sbin/$NAME
CONFIGFILE=/usr/local/openresty/nginx/conf/$NAME.conf
PIDFILE=/usr/local/openresty/nginx/logs/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
set -e
[ -x "$DAEMON" ] || exit 0
do_start() {
$DAEMON -c $CONFIGFILE || echo -n "nginx already running"
}
do_stop() {
kill -INT `cat $PIDFILE` || echo -n "nginx not running"
}
do_reload() {
kill -HUP `cat $PIDFILE` || echo -n "nginx can't reload"
}
case "$1" in
start)
echo -n "Starting $DESC: $NAME"
do_start
echo "."
;;
stop)
echo -n "Stopping $DESC: $NAME"
do_stop
echo "."
;;
reload|graceful)
echo -n "Reloading $DESC configuration..."
do_reload
echo "."
;;
restart)
echo -n "Restarting $DESC: $NAME"
do_stop
do_start
echo "."
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|reload|restart}" >&2
exit 3
;;
esac
exit 0
|
把nginx加入chkconfig,并设置开机启动
1
2
|
chkconfig --add nginx
chkconfig nginx on
|
启动、停止、查看状态
1
2
3
|
service nginx start
service nginx stop
service nginx status
|
四、安装GraphicsMagick
1、安装
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
#创建安装目录
mkdir -p /usr/local/src/graphicsmagick
cd /usr/local/src/graphicsmagick
#下载graphicsmagick
wget http://sourceforge.net/projects/graphicsmagick/files/graphicsmagick/1.3.18/GraphicsMagick-1.3.18.tar.gz/download
tar zxvf GraphicsMagick-1.3.18.tar.gz
#下载libjpeg
wget ftp://ftp.pl.freebsd.org/vol/rzm1/GraphicsMagick/delegates/libjpeg-6b.tar.gz
rpm -qa | grep libjpeg
rpm -qa | grep libjpeg | xargs rpm -e --nodeps --allmatches
tar zxvf libjpeg-6b.tar.gz
cd libjpeg-6b
./configure
make
make install
ln -s /usr/local/lib/libjpeg* /lib/
ln -s /usr/local/lib/libjpeg* /lib64/
cd ..
#安装libpng
rpm -qa | grep libpng
rpm -qa | grep libpng | xargs rpm -e --nodeps --allmatches
wget ftp://ftp.pl.freebsd.org/vol/rzm1/GraphicsMagick/delegates/libpng-1.2.49.tar.gz
tar zxvf libpng-1.2.49.tar.gz
cd libpng-1.2.49
./configure
make
make install
ln -s /usr/local/lib/libpng* /lib/
ln -s /usr/local/lib/libpng* /lib64/
cd ../
#安装freetype
wget ftp://ftp.pl.freebsd.org/vol/rzm1/GraphicsMagick/delegates/freetype-2.4.10.tar.gz
tar zxvf freetype-2.4.10.tar.gz
cd freetype-2.4.10
./configure
make install
ln -s /usr/local/lib/freetype* /lib/
ln -s /usr/local/lib/freetype* /lib64/
cd ..
#安装GraphicsMagick
cd GraphicsMagick-1.3.18
./configure --prefix=/usr/local/graphicsmagick-1.3.18
make
make install
#编辑profile文件
vi /etc/profile
#末尾增加以下内容
export GMAGICK_HOME="/usr/local/graphicsmagick-1.3.18"
export PATH="$GMAGICK_HOME/bin:$PATH"
LD_LIBRARY_PATH=$GMAGICK_HOME/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
#保存退出,运行以下命令立即生效配置
source /etc/profile
|
下载libjpeg、libpng、freetype链接如失效可访问:http://www.filewatcher.com/m/libjpeg-6b.tar.gz.961981-0.html
2、用法
原始图片是input.jpg,尺寸:160×120
1)只缩小不放大
1
|
gm convert input.jpg -resize "500x500>" output_1.jpg
|
加了>,表示只有当图片的宽与高,大于给定的宽与高时,才进行“缩小”操作。
生成的图片大小是:160×120,未进行操作
如果不加>,会导致图片被比等放大。
2)等比缩图 (缺点:产生白边)
1
|
gm convert input.jpg -thumbnail "100x100" output_1.jpg
|
生成的图片大小是:100×75
3)非等比缩图,按给定的参数缩图(缺点:长宽比会变化)
1
|
gm convert input.jpg -thumbnail "100x100!" output_2.jpg
|
生成的图片大小是:100×100
4)裁剪后保证等比缩图 (缺点:裁剪了图片的一部分)
1
|
gm convert input.jpg -thumbnail "100x100^" -gravity center -extent 100x100 output_3.jpg
|
生成的图片大小是:100×100,还保证了比例。不过图片经过了裁剪,剪了图片左右两边才达到1:1
5)填充后保证等比缩图 (缺点:要填充颜色,和第一种方法基本一样)
1
|
gm convert input.jpg -thumbnail "100x100" -background gray -gravity center -extent 100x100 output_4.jpg
|
生成的图片大小是:100×100,还保证了比例,同时没有对图片进行任何裁剪,缺失的部分按指定颜色进行填充。
6)裁剪、填充相结合 (缺点:最差的方法)
1
|
gm convert input.jpg -thumbnail "10000@ -background gray -gravity center -extent 100x100 output_5.jpg
|
生成的图片大小是:100×100,这次保证了大小和比例,其中的10000就是100×100的乘积,同时在填充和裁剪之间做了一个平衡。
7)位深度32 转为24
IE6,7,8不支持显示“位深度32”的图片,但IE9、火狐、谷歌浏览器就可以显示。
使用GM,把“位深度32”的图片转换为“位深度24”的图片
输入图片zzz.jpg就是“位深度32”的图片,输出图片 zzz_out.jpg就是“位深度24”的图片
1
|
gm convert -resize 100x100 -colorspace RGB zzz.jpg zzz_out.jpg
|
转完后,图片的颜色会有轻微变化。
更多请参考:http://elf8848.iteye.com/blog/382528
五、相关配置及脚本
1、Nginx配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
user www www;
worker_processes 1;
# 日志级别调试时可设为notice,生产环境请设为error
error_log /usr/local/openresty/nginx/logs/error.log notice;
events
{
use epoll;
worker_connections 51200;
}
http
{
lua_package_path '/usr/local/openresty/nginx/lua/?.lua;;';
server {
listen 80;
server_name img.hopesoft.org;
root /home/wwwroot/img.hopesoft.org;
#/thumbnail目录下的图片请求不经过缩略图模块
location ^~ /thumbnail/ {
}
#对类似_100x100.gif/jpg/png/jpeg进行缩略图处理
location ~* _([0-9]+)x([0-9]+).(gif|jpg|png|jpeg)$ { #匹配文件名规则
root /home/wwwroot/img.hopesoft.org; #站点根目录
set $image_root /home/wwwroot/img.hopesoft.org; #图片目录
set $thumbnail_root /home/wwwroot/img.hopesoft.org/thumbnail; #缩略图存放目录
#如果缩略图文件存在,直接返回
set $file $thumbnail_root$uri;
if (-f $file) {
rewrite ^/(.*)$ /thumbnail/$1 last;
}
#如果缩略图文件不存在,则应用缩略图模块处理
if (!-f $file) {
rewrite_by_lua_file lua/thumbnail.lua;
}
}
}
include vhost/*.conf;
}
|
2、Lua脚本
/usr/local/openresty/nginx/lua/thumbnail.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
-- nginx thumbnail module
-- last update : 2014/8/21
-- version : 0.4.1
local c = require 'config'
--[[
uri :链接地址,如/goods/0007/541/001_328x328.jpg
ngx_img_root :图片根目录
ngx_thumbnail_root:缩略图根目录
img_width :缩略图宽度
img_width :缩略图高度
img_size :缩略图宽x高
img_crop_type :缩略图裁剪类型
cur_uri_reg_model :缩略图uri正则规则
]]
local uri = ngx.var.uri
local ngx_img_root = ngx.var.image_root
local ngx_thumbnail_root = ngx.var.thumbnail_root
local img_width,img_height,img_size,img_crop_type = 0
local cur_uri_reg = c.default_uri_reg
--[[
日志函数
log_level: 默认为ngx.NOTICE
取值范围:ngx.STDERR , ngx.EMERG , ngx.ALERT , ngx.CRIT , ngx.ERR , ngx.WARN , ngx.NOTICE , ngx.INFO , ngx.DEBUG
请配合nginx.conf中error_log的日志级别使用
]]
function lua_log(msg,log_level)
log_level = log_level or c.lua_log_level
if(c.enabled_log) then
ngx.log(log_level,msg)
end
end
-- 匹配链接对应缩略图规则
function table.contains(table,element)
local i = 1
img_crop_type = 0
for _, value in pairs(c.cfg) do
local dir = value['dir']
local sizes = value['sizes']
local uri_reg = value['uri_reg']
_,_,img_width,img_height = string.find(uri,''..dir..'+.*_([0-9]+)x([0-9]+)')
if(img_width and img_height and img_crop_type==0) then
img_size = img_width..'x'..img_height
for _, value in pairs(sizes) do
if(uri_reg) then
lua_log('value[uri_reg]==='..uri_reg)
else
lua_log('value[uri_reg]===nil,dir='..dir..',cur_uri_reg='..cur_uri_reg)
end
cur_uri_reg = uri_reg or cur_uri_reg
if (img_size == value) then
img_crop_type=1
return true
elseif (img_size..'_' == value) then
img_crop_type=2
return true
elseif (img_size..'!' == value) then
img_crop_type=3
return true
elseif (img_size..'^' == value) then
img_crop_type=4
return true
elseif (img_size..'>' == value) then
img_crop_type=5
return true
elseif (img_size..'$' == value) then
img_crop_type=6
img_size = img_width..'x'
return true
end
end
end
i=i+1
end
return false
end
-- 拼接gm命令
local function generate_gm_command(img_crop_type,img_original_path,img_size,img_thumbnail_path)
local cmd = c.gm_path .. ' convert ' .. img_original_path
if (img_crop_type == 1) then
cmd = cmd .. ' -thumbnail ' .. img_size .. ' -background ' .. c.img_background_color .. ' -gravity center -extent ' .. img_size
elseif (img_crop_type == 2) then
cmd = cmd .. ' -thumbnail ' .. img_size
elseif (img_crop_type == 3) then
cmd = cmd .. ' -thumbnail "' .. img_size .. '!" -extent ' .. img_size
elseif (img_crop_type == 4) then
cmd = cmd .. ' -thumbnail "' .. img_size .. '^" -extent ' .. img_size
elseif (img_crop_type == 5 or img_crop_type == 6) then
cmd = cmd .. ' -resize "' .. img_size .. '>"'
else
lua_log('img_crop_type error:'..img_crop_type,ngx.ERR)
ngx.exit(404)
end
cmd = cmd .. ' ' .. img_thumbnail_path
return cmd
end
lua_log("ngx_thumbnail_root======="..ngx_thumbnail_root)
if not table.contains(c.cfg, uri) then
lua_log(uri..' is not match!',ngx.ERR)
ngx.exit(404)
else
lua_log(uri..' is match!')
local img_original_uri = string.gsub(uri, cur_uri_reg, '')
lua_log('img_original_uri_old===' .. uri)
lua_log('cur_uri_reg===' .. cur_uri_reg)
lua_log('img_original_uri_new===' .. img_original_uri)
local img_exist=io.open(ngx_img_root .. img_original_uri)
if not img_exist then
if not c.enabled_default_img then
lua_log(img_original_uri..' is not exist!',ngx.ERR)
ngx.exit(404)
else
img_exist=io.open(ngx_img_root .. c.default_img_uri)
if img_exist then
lua_log(img_original_uri .. ' is not exist! crop image with default image')
img_original_uri = c.default_img_uri
else
lua_log(img_original_uri..' is not exist!',ngx.ERR)
ngx.exit(404)
end
end
end
local img_original_path = ngx_img_root .. img_original_uri
local img_thumbnail_path = ngx_thumbnail_root .. uri
local gm_command = generate_gm_command(img_crop_type,img_original_path,img_size,img_thumbnail_path)
if (gm_command) then
lua_log('gm_command======'..gm_command)
_,_,img_thumbnail_dir,img__thumbnail_filename=string.find(img_thumbnail_path,'(.-)([^/]*)$')
os.execute('mkdir -p '..img_thumbnail_dir)
os.execute(gm_command)
end
ngx.req.set_uri('/thumbnail'..uri)
end
|
/usr/local/openresty/nginx/lua/config.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
-- nginx thumbnail module
-- last update : 2014/8/21
-- version : 0.4.1
module(...,package.seeall)
--[[
enabled_log: 是否打开日志
lua_log_level: 日志记录级别
gm_path: graphicsmagick安装目录
img_background_color: 填充背景色
enabled_default_img: 是否显示默认图片
default_img_uri: 默认图片链接
default_uri_reg: 缩略图正则匹配模式,可自定义
_[0-9]+x[0-9] 对应:001_100x100.jpg
_[0-9]+x[0-9]+[.jpg|.png|.gif]+ 对应:001.jpg_100x100.jpg
]]
enabled_log = true
lua_log_level = ngx.NOTICE
gm_path = '/usr/local/graphicsmagick-1.3.18/bin/gm'
img_background_color = 'white'
enabled_default_img = true
default_img_uri = '/default/notfound.jpg'
default_uri_reg = '_[0-9]+x[0-9]+'
--[[
配置项,对目录、缩略图尺寸、裁剪类型进行配置,匹配后才进行缩略图处理
1.sizes={'350x350'} 填充后保证等比缩图
2.sizes={'300x300_'}等比缩图
3.sizes={'250x250!'}非等比缩图,按给定的参数缩图(缺点:长宽比会变化)
4.sizes={'50x50^'}裁剪后保证等比缩图 (缺点:裁剪了图片的一部分)
5.sizes={'100x100>'}只缩小不放大
6.sizes={'140x140$'}限制宽度,只缩小不放大(比如网页版图片用于手机版时)
dir="/" 对应根目录,请放在default之前
dir="default" 对应默认图片尺寸,当原图不存在时,请求该尺寸会以默认图片生成缩略图
]]
cfg = {
{
dir = 'photos',
sizes = {'50x50^','100x100>','140x140$','250x250!','300x300_','350x350'},
},
{ dir = 'avatars',
sizes = {'50x50^','80x80'},
},
{
dir = 'mall',
sizes = {'130x130!','228x228!','420x420!'},
uri_reg = '_[0-9]+x[0-9]+[.jpg|.png|.gif]+',
},
{ dir = 'default',
sizes = {'50x50^','100x100>','140x140$','250x250!','300x300_','350x350','80x80'},
}
}
|
六、监控脚本
我们的文件上传和删除由web程序来完成,当web程序删除原始文件时,需要同时删除缩略图,我们使用Linux的inotify来监控原始文件的变化,当有文件修改或删除时,删除相应的缩略图(注:inotify需要linux的内核版本大于等于2.6.13)。
脚本文件/home/shell/monitor_thumbnail.sh内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#!/bin/bash
basedir=/home/wwwroot/img.hopesoft.org/
hostname=img.hopesoft.org
thumbnaildir=thumbnail
excludedir=^${basedir}${thumbnaildir}
/usr/local/bin/inotifywait --exclude $excludedir -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f %e' --event delete,modify ${basedir} | while read date time file event
do
if [ "${file##*.}" = "jpg" -o "${file##*.}" = "jpeg" -o "${file##*.}" = "gif" -o "${file##*.}" = "png" ];then
case $event in(DELETE|MODIFY)
tmpfile=${file/$hostname/$hostname/$thumbnaildir};
filelist=${tmpfile%.*}_*.${tmpfile##*.};
for File in $filelist; do
#echo "rm -rf "$File;
rm -rf $File
done
;;
esac
fi
done
|
1
2
3
4
5
|
#加入启动
vi /etc/rc.d/rc.local
#增加下行
nohup /home/script/delete_thumbnail.sh &
|
关于inotify的更多资料,请参考:http://www.1987.name/637.html
七、参考文档
1、OpenResty官网
http://openresty.com/cn/index.html
2、HttpLuaModule模块介绍
http://wiki.nginx.org/HttpLuaModule
3、[老王]Nginx与Lua
http://huoding.com/2012/08/31/156
4、[老王]尝试使用GraphicsMagick的缩略图功能
http://hi.baidu.com/thinkinginlamp/item/753d86383545d10fcfb9fe14
5、GraphicsMagick安装及使用
http://www.cnblogs.com/javapro/archive/2013/04/28/3048393.html
6、Lua程序设计
http://book.luaer.cn/
7、灵活自定义缩略图片尺寸大小方案分享(nginx,lua_nginx,GraphicsMagick)
http://www.iteye.com/topic/1125126
8、揭秘淘宝286亿海量图片存储与处理架构
http://wenku.baidu.com/view/7dc77b2e7375a417866f8ff0.html
9、django-nginx-image
https://github.com/adw0rd/django-nginx-image
10、Lua中的正则表达式
http://blog.sina.com.cn/s/blog_512f462201016u3b.html
八、示例图片(图片来自老王博客)
原始图片(160×120)
1、填充后保证等比缩图(sizes={’350×350′} )
2、等比缩图(sizes={’300x300_’})
3、非等比缩图,按给定的参数缩图,长宽比会变化(sizes={’250×250!’})
4、裁剪后保证等比缩图,裁剪了图片的一部分(sizes={’50×50^’})
5、只缩小不放大(sizes={’100×100>’})
6、限制宽度,只缩小不放大(比如网页版图片用于手机版时)(sizes={’140×140$’})
原图不存在时
1、当配置显示默认图片,且路径及缩略图尺寸符合时,用默认图片填充
2、当配置不显示默认图片或路径及缩略图尺寸不符合时,返回404
九、Github
项目地址:https://github.com/hopesoft/nginx-lua-image-module
问题反馈:https://github.com/hopesoft/nginx-lua-image-module/issues