最近在做壁纸的项目,会要求根据原图生成不同的分辨率来适配手机。目前设计的方案是只保存一张原图,不同分辨率的图片在请求时根据原图动态裁剪,nginx层实现。
例:
原图url:http://s.qdcdn.com/cl/12526976.jpg
客户端请求的url:http://s.qdcdn.com/cl/12526976,240x400.jpg
则在请求时,服务器nginx层根据原图,动态裁剪出240x400分辨率的图片返回给客户端。
nginx层使用http_image_filter_module模块:
http_image_filter_module是nginx提供的集成图片处理模块,支持nginx-0.7.54以后的版本,在网站访问量不是很高磁盘有限不想生成多余的图片文件的前提下可,就可以用它实时缩放图片,旋转图片,验证图片有效性以及获取图片宽高以及图片类型信息,由于是即时计算的结果,所以网站访问量大的话,不建议使用。
我们的业务访问量也很大,但是用到了cdn,即访问顺序是cdn->nginx->图片服务器,cdn会回源访问nginx,nginx动态生成指定分辨率的图片后,下次用户再访问此分辨率图片时,cdn上已经有了缓存,会大大减少并发动态生成缩略图的访问量。
http_image_filter_module模块的安装请自行网上查阅,本文不再讲述。重点讲下http_image_filter_module生成缩略图的两个命令。
http_image_filter_module有以下6个命令,这里重点讲述resize命令和crop命令:
以下是这两个命令官方的解释(官方文档地址 http://nginx.org/en/docs/http/ngx_http_image_filter_module.html#image_filter):
这里我简单做下翻译:
resize - 根据设置按比例得减小图像。比如100*100的图片,而设置是50*25,减小后的图片为25*25。如果你只想设置一个维度,可以用“-”代替。出错时返回415。
crop - 根据设置按比例得减小图像,然后裁剪成跟设置一样大小的图片。比如100*100的图片,而设置是50*25,减小后的图片为50*50,Nginx会选取中间高度25的像素,形成50*25的图片,所以图片会有缺失。如果你只想设置一个维度,可以用“-”代替。出错时返回415。
大家应该看出了两个命令的区别:resize是会保持原图的纵横比去做缩放,不会做裁剪;crop是缩放的基础上按指定的分辨率去裁剪多余的部分。
可以简单的如下记忆:
resize -最小边缩小图片保持图片完整性
crop -最大边缩放图片后截取多余的部分
公司当前服务器使用的是resize命令,我此次的项目是需要在原图的基础上裁剪出壁纸的,所以我要使用的是crop命令。
nginx服务器配置:
原图地址 location配置图片服务器路径即可
缩略图的地址 用正则匹配yrl,拿到宽、高后在里面调用resize
width
height或
即可crop
width
height