Nginx自身提供了一个模块--with-http_image_filter_module
支持图像裁剪,如果只是单一Nginx节点使用,并没有什么问题。但如果是多个nginx都需要支持图像裁剪,那么不得不每个nginx节点在编译的时候都需要考虑启用--with-http_image_filter_module
模块。该模块使用GD库进行裁剪,性能方面也不是很好。我们完全可以使用更高性能,且更灵活的thumbor图像裁剪从而来替代--with-http_image_filter_module
场景
xiaoz的场景是,有多个nginx节点作为CDN集群,对图片等静态资源进行CDN缓存加速。当我访问https://domain.com/123.jpg
的时候我希望带上参数就能生成缩略图,比如我想裁剪一张200 * 150px
像素的缩略图,只需要带上参数访问https://domain.com/123.jpg/cut?w=200&h=150
即可。
使用ProcessOn画一下大概的流程图:
准备工作
- 已经安装Nginx
- 已经安装thumbor,参考:使用Docker搭建一个开源图像裁剪服务thumbor
实现
在你的nginx反向代理配置中(server段内)添加下面的配置:
#图像裁剪
location ~* /(.+)\.(jpg|gif|png|jpeg|webp|bmp)/cut {
#声明完整的请求地址
set $foo $scheme://$host/$1.$2;
add_header XCDN-Cut 'success';
#忽略源站header,强制缓存
proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie Vary;
proxy_connect_timeout 5;
# Default is HTTP/1, keepalive is only enabled in HTTP/1.1
proxy_http_version 1.1;
proxy_set_header Connection "";
#chunked_transfer_encoding off;
#反向代理图像裁剪
proxy_pass http://192.168.123.4:8888/unsafe/${arg_w}x${arg_h}/$foo;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
...
}
上面的配置是匹配图像格式,并使用thumbor进行裁剪,大概解释下上面参数含义
set $foo $scheme://$host/$1.$2;
这一句是获取完整的图片地址(如https://domain.com/123.jpg
),并赋值给变量$foo
add_header XCDN-Cut 'success';
添加了一个自定义header响应字段XCDN-Cut
,方便判断和调试proxy_pass
指令中我们请求了thumbor的HTTP API进行图像裁剪,http://192.168.123.4:8888/
改成你自己的thumbor地址
以上只是最基础的实现,具体规则请根据实际情况调整,比如缓存、防盗链等。
总结
通过上述方式,无需在nginx上额外编译--with-http_image_filter_module
模块即可赋予nginx图像裁剪的能力,有多个nginx节点的情况下,依赖thumbor进行集中裁剪图像更加简单方便。
如果想要用其他方法例如trim fit-in 等方法处理图片,也想做成反向代理的方式,怎么办?
你好,请问{arg_w}获取的值为空,怎么解决。感谢
需要裁剪的图片路径格式为:https://domain.com/123.jpg/cut&w=200&h=150
你看看路径参数对不对,URL中的w参数对应nginx上的arg_w
确认路径和参数没有问题,设置反代后能显示图片不能裁剪大小
第二&换成?可以了。。
/cut?w=200&h=150 搞定
不好意思,你这个参数是正确的,我文章里面的参数符号整错了,第一个参数应该用?开头
原理有点复杂,还没能搞懂