本站使用的是独立的文件服务器,在需要显示大图片微缩图的场景中,之前都是事先用程序将图片切割好,然后通过完全不同的 URL 返回给前端显示。这种方式复杂且笨拙,本文介绍在 Nginx 中使用 ngx_http_image_filter_module
模块来处理简单的图片转换,可以轻松实现图片缩放、旋转等操作。
服务器环境 ubuntu。
一、确认 Nginx 已集成 http_image_filter_module
在终端中执行:
nginx -V
检查打印信息中是否存在 --with-http_image_filter_module
,有的话则说明 Nginx 已集成了该模块,可以继续;否则需要自行编译安装。
二、Nginx 配置
在 nginx.conf
根节点添加 load_module
命令加载动态库,动态库的位置在不同系统中可能不一样。
load_module /usr/share/nginx/modules/ngx_http_image_filter_module.so;
在对应的 Nginx server 中添加对图片文件的处理:
location ~* \.(jpg|jpeg|webp|png|gif)$ {
...
set $img_width "-";
if ($arg_resize_w ~* "^[0-9]+$") {
set $img_width $arg_resize_w;
}
image_filter resize $img_width -;
image_filter_buffer 10M;
image_filter_jpeg_quality 95;
image_filter_webp_quality 95;
image_filter_transparency on;
image_filter_interlace on;
}
以上配置生效后,请求图片资源时携带 resize_w
参数即可返回指定宽度,高度等比例缩放的图片。
下面是同一个图片资源返回的宽度为150和300像素图片的示例:
三、http_image_filter_module
参数含义
image_filter
可能的取值有:
- off:禁用处理。
- resize width height:缩放,保持一个纬度的原始大小应指定为“-”。
- rotate 90|180|270:指定逆时针旋转图像的度数。
image_filter_buffer
读取图像缓冲区的最大大小。当超过时将返回 415 状态码。
image_filter_jpeg_quality
JPEG 格式图片质量,最大推荐值为 95。
image_filter_webp_quality
webp 格式图片质量。
image_filter_transparency
用指定的颜色转换 GIF 图像或 PNG 图像时是否应保持透明度。
image_filter_interlace
启用后图像呈现的是渐进式加载,即图片显示从模糊到清晰。这种效果用户体验更好,但更消耗服务资源。
参考官方文档说明:Module http-image-filter-module
四、使用 CDN 缓存
以上配置仅仅完成了 Nginx 图片实时缩放功能,但要部署到线上还是要考虑下性能。最优的方案是当请求图片缩放后将处理后的图片保存在本地,下次再次请求同样大小的图片时直接返回即可。
在我最初的设想中,Nginx 应该可以很方便的实现我的需求,但实际调研发现仅依赖 Nginx 实现 image_filter
缩放后的图片缓存比较麻烦,甚至无从下手。
因此,那就保持 Nginx 单纯的图片处理能力,再在 Nginx 之上加一层 CDN 缓存,达到和云服务商 OSS 存储服务中图片缩放处理等类似的效果。
留言板