我看到你在 README.md 中提到:
“使用 gifuct-js 解析 GIF,使用 gif.js 生成 GIF。做了些处理,生成速度贼快”
以及在你的博客草稿 2021-11-11-DOM 生成 GIF.md 中看到详细介绍了这两个 js 组件。
然后最近我正好处理 GIF 相关代码时有些新的发现,这里分享一下:
一、推荐 @flyskywhy/gifuct-js
你博客草稿里的“patch 表示当前帧图,数据格式是 Uint8ClampedArray,可以使用 putImageData 在 canvas 渲染”这句话是有瑕疵的,因为对于大部分 GIF 文件来说,只有第一帧的 patch 代表全高全宽的帧图,后续帧一般只是高宽比较小的帧图,也就是 patch 的含义——在上一帧基础上的“补丁”。而且此时如果 GIF 的 disposalType === 2 的话,就容易出现 matt-way/gifuct-js#39 所提到的在 putImageData 后出现 black pixels
在我改进的 @flyskywhy/gifuct-js 中为每一帧的数据结构添加了一个与 patch 平级的 imageData ,这个就是全高全宽的了。当然参照 @flyskywhy/gifuct-js 代码中生成 imageData 的过程,将相关代码添加到 APP 中并继续使用官方的 gifuct-js 也是可以解决这个 disposalType === 2 时的问题的。
另外由于官方的 gifuct-js 不再更新了,所以我的 @flyskywhy/gifuct-js 还有一些其它改进,比如参照 omggif.js 那样让透明色的 RGBA 四个字节都是 0 而不是仅仅 A 这一个字节是 0
二、推荐 gifenc
我曾经维护过一个仓库 react-native-gifencoder ,它基本上也是一个gif.js 的 fork
但在我的 react-native-runescape-text 中我放弃了使用自己的 react-native-gifencoder ,转而使用 gifenc ,参考 Fix when one color e.g. '#ff0000' only have 1 or 2 or 3 pixel in one frame, the generated gif pixel will be '#9f0000'; fix some frame not transparent but black; reduce gif size 10x 所说的颜色修正、 GIF 文件体积小十倍
另外还有的好处是它是有 npm 包的,而且可以选择不使用 WebWorker (速度貌似比 gif.js 更快所以我的 APP 就没有使用 WebWorker)。