博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用 Nginx 的 ngx_http_image_filter_module 做实时的图片缩略图
阅读量:6041 次
发布时间:2019-06-20

本文共 4023 字,大约阅读时间需要 13 分钟。

  hot3.png

你还在用  生成网站的上传图片缩略图吗?其实有更好的方法一部到位,简单有效。

现而今有非常多的云存储服务支持图片空间,并根据设定的规则来生成空间里面的图片缩略图了,例如 UpYun、Aliyun OSS 都支持。

但有时候我们会因为一些其他的考虑(例如:价格因素),选择本地文件存储上传文件,这个时候,我们如何实现图片缩略图呢?

其实 Nginx 内置了  可以帮助你处理图片:

  • 缩放
  • 裁剪
  • 调整图片品质
  • 旋转
  • 锐化

我们常用的可能就是缩放和裁剪了,根据业务和设计需要,在合适的位置不同尺寸的缩略图。

安装

可能一些标准的 Nginx 安装包没有带这个 module 的,你需要使用 Nginx 官方的源安装,并额外安装 nginx-module-image-filter 这个包:

curl -O http://nginx.org/keys/nginx_signing.keysudo apt-key add nginx_signing.keysudo bash -c 'echo "deb http://nginx.org/packages/ubuntu/ $(lsb_release -cs) nginxdeb-src http://nginx.org/packages/ubuntu/ $(lsb_release -cs) nginx" > /etc/apt/sources.list.d/nginx-stable.list'sudo apt-get updatesudo apt-get install -y nginx nginx-module-image-filter

也可以直接用做好的 

curl -sSL https://git.io/vVHhf | bash

场景

以 Ruby China 的场景为例,我设计了下面几种不同的缩略图版本:

版本名称 限定尺寸 (px) 缩略方式
large 1920 限定宽度,高度自适应
lg 192x192 固定宽度和高度
md 96x96 固定宽度和高度
sm 48x48 固定宽度和高度
xs 32x32 固定宽度和高度

配置 Nginx

假定我们的上传文件存放在 /var/www/homeland/public/uploads 里面。

下面是 Ruby China 这个缩略图规则的完整 Nginx 配置:

/etc/nginx/nginx.conf

user nobody;worker_processes auto;pid /var/www/pids/nginx.pid;daemon on;# 载入 ngx_http_image_filter_moduleload_module modules/ngx_http_image_filter_module.so;http {   # ... 省略}

/etc/nginx/conf.d/ruby-china.conf

proxy_cache_path /var/www/cache/uploads-thumb levels=1:2 keys_zone=uploads_thumb:10m max_size=50G;server {  listen 80 default_server;  listen 443 ssl http2;  root /var/www/homeland/public;  location /uploads {    expires 7d;    gzip_static on;    add_header Cache-Control public;    add_header X-Pownered "nginx_image_filter";    # HTTP Response Header 增加 proxy_cache 的命中状态,以便于以后调试,检查问题    add_header X-Cache-Status $upstream_cache_status;    proxy_pass http://127.0.0.1/_img/uploads;    # 将缩略图缓存在服务,避免每次请求都重新生成    proxy_cache uploads_thumb;    # 当收到 HTTP Header Pragma: no-cache 的时候,忽略 proxy_cache    # 此配置能让浏览器强制刷新的时候,忽略 proxy_cache 重新生成缩略图    proxy_cache_bypass $http_pragma;    # 由于 Upload 文件一般都没参数的,所以至今用 host + document_uri 作为    proxy_cache_key "$host$document_uri";    # 有效的文件,在服务器缓存 7 天    proxy_cache_valid 200 7d;    proxy_cache_use_stale error timeout invalid_header updating;    proxy_cache_revalidate on;    # 处理 proxy 的 error    proxy_intercept_errors on;    error_page   415 = /assets/415.png;    error_page   404 = /assets/404.png;  }  # 原始图片  location /_img/uploads {    alias /var/www/homeland/public/uploads/$filename;    expires 7d;  }  # 缩略图  location ~* /_img/uploads/(.+)!(large|lg|md|sm|xs)$ {    set $filename /uploads/$1;    if (-f $filename) {      break;    }    # 根据 URL 地址 ! 后面的图片版本来准备好需要的参数(宽度、高度、裁剪或缩放)    set $img_version $2;    set $img_type resize;    set $img_w    -;    set $img_h    -;    if ($img_version = 'large') {      set $img_type resize;      set $img_w    1920;    }    if ($img_version = 'lg') {      set $img_type crop;      set $img_w    192;      set $img_h    192;    }    if ($img_version = 'md') {      set $img_type crop;      set $img_w    96;      set $img_h    96;    }    if ($img_version = 'sm') {      set $img_type crop;      set $img_w    48;      set $img_h    48;    }    if ($img_version = 'xs') {      set $img_type crop;      set $img_w    32;      set $img_h    32;    }    rewrite ^ /_$img_type;  }  # 缩放图片的处理  location /_resize {    alias /var/www/homeland/public$filename;    image_filter resize $img_w $img_h;    image_filter_jpeg_quality 95;    image_filter_buffer         20M;    image_filter_interlace      on;  }  # 裁剪图片的处理  location /_crop {    alias /var/www/homeland/public$filename;    image_filter crop $img_w $img_h;    image_filter_jpeg_quality 95;    image_filter_buffer         20M;    image_filter_interlace      on;  }}

你可能会觉得上面为何写得这么绕啊!

没办法,Nginx 不支持在 if {} 这个 block 里面用 image_filter 函数,image_filter 的第一个参数 resize/crop也不能用变量的方式传输,所以...

然后,重启 Nginx,就可以尝试了。

注意点

  • 由于开启了 proxy_cache 缩略图将会在服务器上以文件的形式存在,你需要确保每次上传新文件名尽可能的是唯一的(例如用时间,或文件内容 MD5 作为文件名,参考 )
  • 浏览器强制刷新,会发起 Pragma: no-cache 的 Request Header,Nginx 会忽略 proxy_cache 重新生成图片。

效果演示

 

  • Original - 
  • large - 
  • lg - 
  • md - 
  • sm - 
  • xs - 

扩展阅读

 

转载于:https://my.oschina.net/voole/blog/1844471

你可能感兴趣的文章
C#+QQEmail自动发送邮件
查看>>
[Hadoop]MapReduce多输出
查看>>
Android Activity详解(一)
查看>>
快准车服完成3000万元A+轮融资,年底将开始B轮融资
查看>>
让我去健身的不是漂亮小姐姐,居然是贝叶斯统计!
查看>>
MySQL 数据约束
查看>>
我的友情链接
查看>>
SERVLET容器简介与JSP的关系
查看>>
《服务器SSH Public Key认证指南》-补充
查看>>
我的友情链接
查看>>
Java break continue return 的区别
查看>>
算法(Algorithms)第4版 练习 1.3.4
查看>>
jquery easyUI checkbox复选项获取并传后台
查看>>
浅析NopCommerce的多语言方案
查看>>
设计模式之简单工厂模式
查看>>
C++中变量的持续性、链接性和作用域详解
查看>>
2017 4月5日上午
查看>>
Google Chrome开发者工具
查看>>
第一阶段冲刺报告(一)
查看>>
使用crontab调度任务
查看>>