示例地址 zaqmjuop.github.io/libgif/
从gif文件读取图像数据
gif内容示例
从字符串读取二进制数字的方法
// 字符转数字
'GIF'.charCodeAt(0) // 71
'GIF'.charCodeAt(1) // 73
'GIF'.charCodeAt(2) // 70
// 数字转字符
String.fromCharCode(71) // 'G'
String.fromCharCode(73) // 'I'
String.fromCharCode(70) // 'F'
// 十进制转2进制
(247).toString(2) // '11110111'
unsigned 类型: 256进制的2位数,比如 [144, 1] 的取值是 144 + 1 * 256 = 400
GIF89a编码内容结构
- 整体结构
- 连续字块
- 文件头块
- 图像内容块
- 像素插行
GIF89a的像素插行分4步,以正常像素行号 [0, 1, 2, 3, 4, ..., 19]为例
从第 0 行开始间隔 8 行插入,即像素行号排序 0, 8, 16
从第 4 行开始间隔 8 行插入,即像素行号排序 4, 12
从第 2 行开始间隔 4 行插入,即像素行号排序 2, 6, 10, 14, 18
从第 1 行开始间隔 2 行插入,即像素行号排序 1, 3, 5, 7, 9, 11, 13, 15, 17, 19
扩展块
- 应用程序扩展块
- 图形扩展块,作用范围是紧跟着的帧图像块
- 注释扩展块
- 纯文本扩展块
扩展块描述的内容是一个带有位置、大小、颜色的文本,作用像是图片的水印文字,但我从没见过出现过这个扩展块
- 文件结束符:';'即59
2. 播放控制
理想的执行过程应该是下载一帧,解码一帧,渲染一帧。所以下载、解码和播放应该是并行执行。
解码器解码时,解码进度可能会超过下载进度,数据流读取器读取方法的读取位置就会到源数据的末位之后,那么就要等待下载数据增加后再返回,所以流读取器读取方法是异步函数。
播放器播放时,播放进度可能超过解码进度,所以播放函数要轮询从解码缓存池读取解码数据,再播放下一帧
3. gif编码用到的LZW压缩
- 示例参数
- 示例结果
- 解压缩过程
- 示例运行过程