温馨提示:学习本文之前,需要对图片处理工具有一定的了解,可以看下我之前写的图片处理专栏
本文要介绍的内容很厉害,系好安全带,发车了~
不知道读者有没有使用过类似阿里云文件URL处理图片的功能
通过在原图链接后拼接图片处理参数,可以实现图片实时处理!!!听起来很厉害吧,那我们自己能否实现这一功能呢?
其实要实现起来也很简单 ^-^
在线图片处理的整体流程
在展开今天内容之前,先大概讲下整个接口的处理数据流是怎样的,让大家有个宏观的印象。
1、整体流程
2、图片服务(image service)接口处理流程
这里有个下载原图的步骤,由于图片服务并没有源文件,所以必须先将源文件拉取到本地,才能进行后续处理
由于请求会先经过存储网关,所以会解析原图的内网地址,通过内网带宽拉取图片,速度是很快的
分析阶段
图片服务收到请求,处理逻辑为:解析参数 -> 校验参数 -> 拼接处理命令 -> GM执行命令 -> 生成结果文件 -> 返回文件
所以关键步骤就是拼接处理命令
目前实现了:图片缩放、自适应方向、质量变换、格式转换、裁剪、水印等功能
一般最快速的实现方式就是循环将参数转为对应的命令,拼接字符串,但是这不符合“开闭原则”呀,有没有跟优雅的方式,可以实现功能扩展而不需要改动原逻辑呢?今天的主角——
装饰器模式
隆重登场~
什么是装饰器模式?
在不影响其他对象的情况下,以动态地给一个对象添加一些额外的职责。
该模式一般包含如下的角色:
- Component抽象构件角色:真实对象和装饰对象有相同的接口。这样,客户端对象就能够以与真实对象相同的方式同装饰对象交互
- ConcreteComponent具体构件角色:定义一个具体的对象,也可以给这个对象添加一些职责
- Decorator装饰角色:持有一个抽象构件的引用。装饰对象接受所有客户端的请求,并把这些请求转发给真实的对象。这样,就能在真实对象调用前后增加新的功能
- ConcreteDecorator具体装饰角色:负责给构件对象增加新的责任
代码实现
本次实现的URL图片处理参考阿里云的链接拼接方式
1、参数解析
假设现在有一个请求,请求链接为:
xxx.test.com/test.jpg?s-…
该链接的图片处理参数部分为:s-oss-process=image/resize,m_mfit,w_100,h_100/quality,q_80/format,jpg
s-oss-process=image 主要是用于让网关识别这是图片处理的流量,将流量转发到具体的服务
所以实际获取到需要解析的参数为:resize,m_mfit,w_100,h_100/quality,q_80/format,jpg
观察参数可以发现,每个具体的功能用“/”分隔,功能中第一个逗号前面的是操作名,后面是操作的具体参数,核心代码如下:
1 | java复制代码// 这里假设imageProcess已经是上面需要解析的部分(resize,m_mfit,w_100,h_100/quality,q_80/format,jpg) |
我们将URL解析成一个有序的Map:
- resize:m_mfit,w_100,h_100
- quality:q_80
- format:jpg
2、拼接处理命令
这里就用到了装饰器模式,先看看结构图:
1)定义图片处理顶层接口(Component)
1 | java复制代码/** |
2)定义具体的构建角色(ConcreteComponent)
1 | java复制代码/** |
3)定义图片处理的装饰角色(Decorator)
该对象持有ImageProcess
具体构建角色对象的引用,同时自己也继承ImageProcess
接口,通过构造方法接收具体的处理参数,重写接口的方法,实现对具体构件对象的功能增强。
1 | java复制代码/** |
4)实现具体的装饰器角色(ConcreteDecorator)
这里只列举一个例子,其他实现也很类似
1 | java复制代码/** |
外层通过第1步解析参数得到的Map,调用装饰器,生成具体的执行命令:
1 | java复制代码/** |
至此,我们将URL传递的参数,解析为GraphicsMagick
的处理命令:convert ${srcPath} -resize 100x100^ -quality 80 ${disPath}.jpg
如果对上面的命令感觉很懵的话,可以看下:GraphicsMagick实现云服务商基础图片处理
3、生成结果文件
将第2步生成的图片处理命令丢给GM进程进行处理,就能得到结果文件啦~
这里引入了gm4java这个工具提供的进程池控制GM进程数(代码中注入即可:PooledGMService)
1 | xml复制代码<dependency> |
可以参考看下:Springboot集成GraphicsMagick
End
以上就是在线图片处理的整个处理过程,是不是发现逻辑其实很简单,使用装饰器模式很方便的让我们后续增加更多的功能。这就是具体设计模式在实际项目中的应用!
后续对服务压测结束后,可能会输出关于结果文件采用 普通方式 和 “零拷贝”方式 响应给调用方的文章,大家有兴趣可以点个关注留意下~
本文转载自: 掘金