Nginx图片自动裁剪,根据访问尺寸输出图片
Nginx 本身不带图片裁剪能力,需要借助 ngx_http_image_filter_module 模块。
它可以根据 URL 中传入的宽高参数,在图片被访问时实时生成对应尺寸的图片。
下面按零基础可执行的方式,把安装、配置、验证和避坑一次讲清。
先确认模块是否可用
很多预编译的 Nginx 默认没有包含 image_filter 模块,直接写配置会报 unknown directive "image_filter"。
执行命令查看:
nginx -V 2>&1 | grep -o with-http_image_filter_module
如果输出 with-http_image_filter_module,说明已支持,跳到下一节。
如果没有输出,需要重新编译或安装带该模块的版本。
以宝塔面板为例,可在软件商店的 Nginx 设置中选择“编译安装”,在模块列表里勾选 image_filter 后重新安装。
注意:image_filter 依赖 GD 库,编译前确保系统已安装 libgd-dev(Debian/Ubuntu)或 gd-devel(CentOS)。
配置按尺寸输出的 location
假设原始图片放在 /www/wwwroot/site/uploads/ 目录,希望通过 /thumb/图片名? 的方式访问缩略图。
w=200&h=200
在站点配置的 server 块内加入:
location ~ ^/thumb/(.+)$ {
set $width $arg_w;
set $height $arg_h;
if ($width = "") { set $width -; }
if ($height = "") { set $height -; }
image_filter resize $width $height;
image_filter_jpeg_quality 85;
image_filter_buffer 10M;
alias /www/wwwroot/site/uploads/$1;
}
关键点说明:
$arg_w和$arg_h读取 URL 中的查询参数,-表示该维度不限制。image_filter resize按比例缩放到指定宽高内,保持原图比例。image_filter_buffer限制可处理图片的最大内存,默认 1M,大图容易触发 415 错误,建议调大。alias指向真实图片目录,$1是 URL 中匹配到的文件名。
改完配置后执行 nginx -t 检查语法,再 nginx -s reload 生效。
缓存与性能避坑
实时裁剪会消耗 CPU,每次请求都重新处理会拖慢响应。
建议加一层缓存。
在 location 内增加:
image_filter_cache proxy_cache;
image_filter_cache_path /tmp/nginx_thumb levels=1:2 keys_zone=thumb_cache:10m max_size=500m inactive=7d;
image_filter_cache_valid 200 7d;
同时要保证缓存目录存在且 Nginx 运行用户有写权限:
mkdir -p /tmp/nginx_thumb
chown -R www:www /tmp/nginx_thumb
另一个常见坑是 URL 中带中文文件名,建议对图片名做 URL 编码,或者直接用英文数字命名,避免 alias 匹配失败返回 404。
验证裁剪是否生效
配置完成后,用浏览器或 curl 访问:
curl -I "http://你的域名/thumb/test.jpg?w=200&h=200"
预期返回 HTTP/1.1 200 OK,并且 Content-Type 为 image/jpeg。
下载后查看图片实际尺寸应为 200x200 以内且保持比例。
如果返回 404,检查 alias 路径和文件名是否一致;
返回 415,通常是 image_filter_buffer 太小;
返回 500,多半是 GD 库缺失或图片格式不支持。
确认无误后,前端页面就可以按需拼接尺寸参数,例如列表页用 ?,详情页用原图地址,实现一套图片多尺寸输出。
w=300
常见疑问
裁剪后的图片会自动保存吗? 默认不保存,每次请求实时处理。
开启 image_filter_cache 后,处理结果会缓存到指定目录,后续命中缓存直接返回。
支持 WebP 吗? 取决于编译时的 GD 库版本。
较新的 libgd 支持 WebP,但建议先用一张 WebP 图片实测,以实际返回结果为准。
原图会被修改吗? 不会。
image_filter 只处理输出流,不写回原文件,原图始终保留。
能限制只允许特定尺寸吗? 可以。
在 location 里用 if 判断 $arg_w 是否在允许列表内,不在则返回 403,避免被恶意拼接超大尺寸消耗资源。
如果你正在配置 Nginx 图片自动裁剪,建议先在测试站点跑通完整流程,确认模块、权限和缓存都正常后,再同步到生产环境。