• OpenResty(Nginx)+Lua+GraphicsMagick实现缩略图功能


    OpenResty(Nginx)+Lua+GraphicsMagick实现缩略图功能

    一、背景说明
    大多数网站基本都涉及到图片缩略图的处理,比如新闻配图、电商商品图等,特别是电商类网站,每个商品图对应多个不同尺寸的缩略图,用于不同的页面。

    初期访问量少时,处理流程一般由web程序在上传成功后,同时生成相应缩略图。这种方式在访问量小,单机部署时没有问题。当访问量逐渐加大,服务器由单台变为多台时,这种方式扩展性较差。

    以下有几种方案可以解决这个问题:
    1、使用七牛又拍云提供的云存储及数据处理服务,解决图片的处理、存储、多节点访问速度的问题,这种方式优点是方案成熟,相应的有一定费用和开发工作,另外有一些小概率的风险,比如云服务挂掉影响本站访问。
    2、使用第三方的图片处理程序,比如zimg,点击查看使用手册@招牌疯子开发。zimg的性能和扩展性不错,文档也很完善,会继续保持关注。
    3、自己造轮子,根据自身业务,将生成缩略图功能独立出来,与web程序解耦。

    我们采用的是第三种方案,参考了网友的基础代码,利用OpenResty(Nginx)+Lua+GraphicsMagick实现缩略图功能,图片上传及删除还是由web程序处理,缩略图由单独模块完成。目前可实现配置路径及缩略尺寸,无图片时显示默认图片,支持多种缩放方式等,后续可基于GraphicsMagick实现更多功能

    二、相关规范
    1、文件夹规划

    其中img.hopesoft.org为图片站点根目录,avatars和photos目录是原图目录,可根据目录设置不同的缩略图尺寸,default文件夹的notfound.jpg文件是在未找到原图时的默认图片,thumbnail文件夹用来存放缩略图,可定时清理。

    2、链接地址
    原图访问地址:http://img.hopesoft.org/photos/001/001.jpg
    缩略图访问地址:http://img.hopesoft.org/photos/001/001_100x100.jpg,(请勿加thumbnail,这个是因为我们原来的原图和缩略图在同一个目录,后来将缩略图单独放了一个文件夹)
    不同目录可设置不同的缩略图规则,如:
    原图访问地址:http://img.xxx.com/mall/001/001.jpg
    缩略图访问地址:http://img.xxx.com/mall/001/001.jpg_100x100.jpg (请勿加thumbnail)

    3、访问流程
    首先判断缩略图是否存在,如存在则直接显示缩略图;
    如不存在则按以下流程处理:

    1. 判断缩略图链接与规则是否匹配,如不匹配,则404退出;如匹配跳至2
    2. 判断原图是否存在,如原图存在则跳至5,如不存在则进入下一步;
    3. 判断是否显示默认图片,如不显示则404退出;如显示则进入下一步
    4. 判断是否存在默认图片,如不存在则404退出;如存在则将默认图片代替原始图片,进入下一步;
    5. 拼接graphicsmagick命令,生成并显示缩略图

    三、安装OpenResty
    1、关于OpenResty(http://openresty.org/cn/

    OpenResty (也称为 ngx_openresty)是一个全功能的 Web 应用服务器,它打包了标准的 Nginx 核心,很多的常用的第三方模块,以及它们的大多数依赖项。
    OpenResty 通过汇聚各种设计精良的 Nginx 模块,
    从而将 Nginx 有效的变成一个强大的 Web 应用服务器,
    这样, Web 开发人员可以使用 Lua 脚本语言调动 Nginx 支持的各种C以及Lua 模块,
    快速构造出足以胜任 10K+ 并发连接响应的超高性能Web 应用系统。更多

    2、安装OpenResty
    注:drizzle-nginx-module模块和nginx-http-concat模块非必选项,各位可按需安装

    3、将OpenResty(Nginx)加入自启动

    文件内容如下

    把nginx加入chkconfig,并设置开机启动

    启动、停止、查看状态

    四、安装GraphicsMagick
    1、安装

    下载libjpeg、libpng、freetype链接如失效可访问:http://www.filewatcher.com/m/libjpeg-6b.tar.gz.961981-0.html

    2、用法

    原始图片是input.jpg,尺寸:160×120

    1)只缩小不放大

    加了>,表示只有当图片的宽与高,大于给定的宽与高时,才进行“缩小”操作。
    生成的图片大小是:160×120,未进行操作
    如果不加>,会导致图片被比等放大。

    2)等比缩图 (缺点:产生白边)

    生成的图片大小是:100×75

    3)非等比缩图,按给定的参数缩图(缺点:长宽比会变化)

    生成的图片大小是:100×100

    4)裁剪后保证等比缩图 (缺点:裁剪了图片的一部分)

    生成的图片大小是:100×100,还保证了比例。不过图片经过了裁剪,剪了图片左右两边才达到1:1

    5)填充后保证等比缩图 (缺点:要填充颜色,和第一种方法基本一样)

    生成的图片大小是:100×100,还保证了比例,同时没有对图片进行任何裁剪,缺失的部分按指定颜色进行填充。

    6)裁剪、填充相结合 (缺点:最差的方法)

    生成的图片大小是:100×100,这次保证了大小和比例,其中的10000就是100×100的乘积,同时在填充和裁剪之间做了一个平衡。

    7)位深度32 转为24
    IE6,7,8不支持显示“位深度32”的图片,但IE9、火狐、谷歌浏览器就可以显示。
    使用GM,把“位深度32”的图片转换为“位深度24”的图片
    输入图片zzz.jpg就是“位深度32”的图片,输出图片 zzz_out.jpg就是“位深度24”的图片

    转完后,图片的颜色会有轻微变化。

    更多请参考:http://elf8848.iteye.com/blog/382528

    五、相关配置及脚本
    1、Nginx配置文件

    2、Lua脚本
    /usr/local/openresty/nginx/lua/thumbnail.lua

    /usr/local/openresty/nginx/lua/config.lua

    六、监控脚本

    我们的文件上传和删除由web程序来完成,当web程序删除原始文件时,需要同时删除缩略图,我们使用Linux的inotify来监控原始文件的变化,当有文件修改或删除时,删除相应的缩略图(注:inotify需要linux的内核版本大于等于2.6.13)。

    脚本文件/home/shell/monitor_thumbnail.sh内容如下:

    关于inotify的更多资料,请参考:http://www.1987.name/637.html

    七、参考文档
    1、OpenResty官网
    http://openresty.com/cn/index.html
    2、HttpLuaModule模块介绍
    http://wiki.nginx.org/HttpLuaModule
    3、[老王]Nginx与Lua
    http://huoding.com/2012/08/31/156
    4、[老王]尝试使用GraphicsMagick的缩略图功能
    http://hi.baidu.com/thinkinginlamp/item/753d86383545d10fcfb9fe14
    5、GraphicsMagick安装及使用
    http://www.cnblogs.com/javapro/archive/2013/04/28/3048393.html
    6、Lua程序设计
    http://book.luaer.cn/
    7、灵活自定义缩略图片尺寸大小方案分享(nginx,lua_nginx,GraphicsMagick)
    http://www.iteye.com/topic/1125126
    8、揭​秘​淘​宝​2​8​6​亿​海​量​图​片​存​储​与​处​理​架​构
    http://wenku.baidu.com/view/7dc77b2e7375a417866f8ff0.html
    9、django-nginx-image
    https://github.com/adw0rd/django-nginx-image
    10、Lua中的正则表达式
    http://blog.sina.com.cn/s/blog_512f462201016u3b.html

    八、示例图片(图片来自老王博客)

    原始图片(160×120)

    1、填充后保证等比缩图(sizes={’350×350′} )

    2、等比缩图(sizes={’300x300_’})

    3、非等比缩图,按给定的参数缩图,长宽比会变化(sizes={’250×250!’})

    4、裁剪后保证等比缩图,裁剪了图片的一部分(sizes={’50×50^’})

    5、只缩小不放大(sizes={’100×100>’})

    6、限制宽度,只缩小不放大(比如网页版图片用于手机版时)(sizes={’140×140$’})

    原图不存在时
    1、当配置显示默认图片,且路径及缩略图尺寸符合时,用默认图片填充

    2、当配置不显示默认图片或路径及缩略图尺寸不符合时,返回404

    九、Github
    项目地址:https://github.com/hopesoft/nginx-lua-image-module
    问题反馈:https://github.com/hopesoft/nginx-lua-image-module/issues

  • 相关阅读:
    Cookie和Session
    HTTP简介
    Python赋值与深浅拷贝
    Python装饰器探险
    Python操作MongoDB数据库
    MongoDB数据库基础
    python操作mysql数据库
    USACO2012 overplanting /// 矩阵切割 递归 oj21547
    USACO2007 The Bale Tower /// DFS oj21160
    USACO2012 Moo /// 模拟 oj21548
  • 原文地址:https://www.cnblogs.com/archoncap/p/4894097.html
Copyright © 2020-2023  润新知