最近,我们cute 的数字图像处理老师让我们看看GIF 的文件格式,然后实现一个均衡化算法。我准备用Ruby 做一个,
但Ruby 对位的操作不如C。还好找到了bit-struct,一个用string 来存储二进制数据的库。
我们会在后面对左图分析。
与针对相片影像而设计的JPEG 不同,GIF 由于采用了8位压缩,最多只能处理256种颜色(至少标准是这样),故不宜于显示真彩图片。
其实GIF 设计得很优美,有三个部分构成:Header,Data Stream,Trailer。
6 Byte 的Header 包括GIF 签名和版本号:
GIF 文件终结符是0x3b。
Data Stream由7 Byte 的Logical Screen Descriptor、Global Color Table(即调色板,可能是256×3 Byte,因为GIF 只能显示256色)以及多张图片组成。每张图片都有Image Descriptor,可能还有数据块和一些扩展模块。数据块包括Local Color Table 和Table Based Image Data。扩展模块有:Graphic Control Extension,Plain Text Extension,Comment Extension,Applicaton Extension。
Logical Screen Descriptor :
Global Color Table :
Image Descriptor:
Local Color Table:
Table Based Image Data:
Graphic Control Extension Block:
Comment Extension Block:
Plain Text Extension Block:
Application Extension Block:
GIF 有两个标准87a(即87版)和89a(即89版)。GIF 89a 只是在87a 的基础上扩充了一点支持动画的功能。
87a 包括GIF Header,Image Block,Trailer 三个部分。而89a包括GIF Header,Graphic Control Extension,Image Block,Trailer 四个部分。
GIF 最大的特点就是支持动画。其实GIF Animation 的格式差不多,也分为四部分:GIF Header,Application Extension,任意个Graphic Control Extension Image Block,Trailer。
由于BitStruct 其实是一个String,我需要一个辅助类来转换成十六进制数。
首先,对Header 分析。
接着是分析Logical Screen Descriptor 的各个字段。
根据Logical Screen Descriptor 的Logical Screen Descriptor 判断是否存在全局调色板。
接下来是处理图片,看流程图:
这里是完整源码。
输出:
可以看出这幅gif 图像有15个模块,掐头去尾共5幅画:
而且每幅画都是Graphic Control Extension Block + Image Descriptor。
图像控制控制块可以放在一个图象块(图象标识符)或文本扩展块的前面,用来控制跟在它后面的第一个图象(或文本)的渲染(Render)形式。图像描述符紧跟其后,包含图像的各种属性。接着是用LZW压缩的数据。