前言
最近在博客后台上传图片的时候,突然发现上传gif图片的时候裁剪图片有问题。既没法裁剪gif指定区域的图片,又没法裁剪指定区域生成一个新的指定大小的gif图。本来想直接去找个裁剪的库直接放上去的,但是找了半天也没找到能够裁剪gif然后生成裁剪区域的gif的库,于是就自己动手了。
探索
如果只是单纯的在Gif上裁剪第一帧图片,倒是有插件能实现,我用的就是react-cropper来进行图片裁剪的。但是这个插件没法裁剪GIF生成另一个GIF图。
我要的效果是下面这样的效果
原图
裁剪后的gif图
然后就去查了下如何实现gif图到gif图的裁剪,虽然没有找到对应的插件,但是找到了两个开源的库。
发现这两个功能一组合不就可以实现我要的那个效果了么。
上传GIF => 通过解析GIF每一帧在Canvas上生成对应的图像 => canvas转成GIF
实现
libgif-js的实现过程
libgif-js
是通过实现对gif路径发起一个请求,然后通过解析请求回来的gif数据来生成GIF实例(包括每一帧的动画,以及大小之类的基础数据),然后通过GIF实例生成对应的canvas
gif.js的实现过程
通过收集libgif-js
转换到canvas上面的每一帧的变化,来生成最终的GIF
。
gif转换到canvas的实现过程
首先到libgif-js这个项目中下载对应的js文件,因为这个库并没有上传npm,所以需要自己去项目中下载。
libgif-js
他这个封装的是对HTML
节点的操作,没法直接去用,因为我是上传文件,获取的File
对象,所以需要对这个文件进行部分修改
- 首先应该接收的是一个
url
路径,可以把File文件
通过URL.createObjectURL(file)
转成成url
,让其进行XMLHttpRequest
请求。 也可以直接传gif
的链接。 - 然后需要传裁剪的区域范围。裁剪的范围大小需要适配原gif的尺寸比例
- 去除
libgif-js
文件里面不需要的代码,只需要其中每一帧的图像集合跟尺寸大小就行
canvas转换到gif的实现过程
监听gif绘制到canvas上的每一帧变化,然后gif