找了很多GIF动图制作的工具,比如将视频转成GIF, 或者将一系列图片转成GIF, 增加背景文案等等功能。很多收费或者用的一些三方库有点点卡顿,或者需要安装一个软件,所以就自己做一款纯前端页面级别的 视频转 GIF 动图工具。
最开始找到一款可使用的库 gifshot, 该库最后一个版本在 2017 年(这篇文档记录截止查看的时间)。该包提供了示例, 其实支持的功能还挺多的,如下:
不过也有一些缺点,查看源码可知,内部实现的时候,是在 omggif 库的基础上, 使用 canvas 对视频流进行截取, 然后通过 getImageData 获取图片资源, 再次进行视图转化后 交给 omggif 一张张图片追加上去 (当然源码中将 omggif 库部分代码直接拷贝下来的), 最终通过生成 base64格式的 GIF 资源。
鉴于上述的一些情况, 所以就基于 omggif
库, 参考 gifshot 库(其中多线程生成图片特征很不错), 在项目中做一款纯 js 的专门处理 canvas 调用 getImageData 方法得到的数据的工具类了, 其他的功能比如 截取视频流, 截取图片列表等等, 来源根据各自的使用场景自定义。该工具类只处理 ImageData 资源。
鉴于上述, 基于omggif
自定义一个生成GIF的功能模块,实际上,将该库部分功能截取下来了。自定义GIF生成主要分如下两个部分功能
gif-tool
可以完全在 woker 中运行, 这样就能将整个 图片资源转化和图片生成 GIF 放在独立线程处理了。不过此处图片特征处理比较耗时, 且可以不按顺序处理, 将这个流程交与子线程处理就好了, 其他的进行任务调度。
图片资源特征抽取比较耗时间, 并且与顺序无关, 参考 gifshot 的方式, 开多个线程处理。生成的图片特征生成GIF, 不能遍历直接生成, 通过任务调度的方式来生成, 以免造成页面卡顿, 且每完成一张就可以将进度显示在页面, 优化体验效果。
因为生成的GIF也不宜过大,且可以支持截取对应的视频区间以及长视频模式处理,所以直接一次性生成,没有分批处理。不过实际工作项目中肯定需要做demo进行对比。
所以选取的整体流程是 截取屏幕瞬间 -> 生成图片数据列表 -> 处理图片特征 -> 增加每一张图片为 GIF 播放瞬间以及停留时间设置 -> 生成供下载的GIF链接
页面信息显示大概如下, 截取图片的数量, 通过帧率来设置截取频率, 展示频率默认一帧等等。支持大时长视频生成GIF预览, 也就是长视频模式。
生成的时候可以明确的看到各个阶段的进度,以及每次设置之后预估的截取数量,如果想截取视频中某一段或者某个范围,可以对时间和区域进行裁剪,效果如下:
其他优化: 目前只做简单的提示,比如多少张可能会卡,实际上可以做更详细的优化,比如预计截取多少张图片会导致卡顿, 预计会截取多少资源到内存等等,从而提示截取帧数是否需要修改。
因为可以完全自定义绘制部分, 所以想要追加啥东西都可以, 最终给 gif-tool 工具处理图片资源即可。
因为暂时没有用到, 所以就没做了,方案详细记录。
最后在线免费体验地址www.nqone.com/gif,如果想要将某些录取的视频操作生成GIF可以试试哦,大致效果如下: