发布时间:2020-02-23 12:31:06来源:阅读:
项目中有个地方需要根据客户端的要求缩放图片。最开始想用PHP来实现这个功能。设想中如果已经存在图片a.jpg,则可以通过类似a_400x400.jpg的方式来获取图片特定尺寸的缩略图。
要实现此功能可以在图片上传的时候就事先裁好指定尺寸的图片,或者在获取的时候拦截请求来实现。
如果使用第一种方法,则只能实现裁剪好预设尺寸的图片,而且会影响到上传图片的效率,如果裁剪失败,也无法后续处理。
使用第二种方式的问题是图片资源存储在一个静态资源的目录,需要在没有图片的情况下将请求转发给PHP去处理。
于是我设想能否在Nginx这一层去做这件事情,恰好Nginx有一个image filter的模块,只不过在编译的时候默认没有编译进去。
手动添加参数编译此模块,开始修改nginx的配置文件。
第一个版本的配置如下:
# 我使用16进制数的方式给图片重命名
location ~* /(.*)/([0-9a-f]+)_(d+)x(d+).(jpg|png|jpeg|gif)$ {
    # 如果存在文件就终止规则
    if (-f $request_filename) {
        break;
    }
    # 设定一些参数
    set $filepath $1;
    set $filename "$2.$5";
    set $thumb    "$2_$3x$4.$5";
    set $width    $3;
    set $height   $4;
    # 如果原文件不存在可以直接返回404
    if (!-f $document_root/$filepath/$filename) {
        return 404;
    }
    # 重写URL
    rewrite /(.*)/([0-9a-f]+)_([0-9x]+).(jpg|png|jpeg|gif) /$1/$2.$4 break;
    # 执行图片缩放
    image_filter test;
    image_filter resize $width $height;
    image_filter_jpeg_quality 75;
}
但是在这个版本的配置中,如果配置原文件不存在,实际上没法正确返回404,而是返回415。过滤还是执行了。
还有一个问题就是在每次访问缩略图的时候都会重新生成,如果访问量比较大的情况下,效率并不高。
进过一系列的实践后,我又改好了一个版本:
location ~* /(.*)/([0-9a-f]+)_(d+)x(d+).(jpg|png|jpeg|gif)$ {
    if (-f $request_filename) {
        break;
    }
    set $filepath $1;
    set $filename "$2.$5";
    set $thumb    "$2_$3x$4.$5";
    set $width    $3;
    set $height   $4;
    if (!-f $document_root/$filepath/$filename) {
        return 404;
    }
    rewrite /(.*)/([0-9a-fx_]+).(.*) /imgcache/$2.$3;
    if (!-f $request_filename) {
        proxy_pass http://127.0.0.1:$server_port/image-resize/$filepath/$filename?width=$width&height=$height;
        break;
    }
    proxy_store          $document_root/imgcache/$thumb;
    proxy_store_access   user:rw  group:rw  all:r;
    proxy_set_header     Host $host;
}
location /image-resize {
    rewrite /(image-resize)/(.*) /$2 break;
    image_filter resize $arg_width $arg_height;
    image_filter_jpeg_quality 75;
    allow 127.0.0.0/8;
    deny all;
}
通过proxy_pass的方式解决415的问题,并通过proxy_store的方式将图片存到指定的目录(imgcache),在每次访问之前先进行判断。
上一篇:Linux命令行操作
2020-05-25
《魔兽世界》8.2联盟部落阵营首领对话曝光!玩家:这是闹哪般?
centos7安装配置squid正向代理
Docker管理指南(5) – 使用systemd控制和配置Docker
Bash使用示例(2) – 内部变量
使用Docker搭建 Java Web运行环境
Lenovo TianYi 310-14IKB 15IKB安全、保修和设置指南V1.0
CS2010DW如何设置无线网络?
CentOS LNMP WordPress自动更新需填写FTP解决方法
USB集线器电涌是怎么回事?