图像处理--GIF和静态图的叠加

不少图片处理软件都有一种功能:用户上传一张静态照片,然后可以从软件提供的一些动态图片(gif)选择一种,常见的是相框之类的,和静态图片合成,得到新的动态图片。这就是GIF和静态图片的叠加。


要实现上面的功能,思路还是比较清晰的。GIF图片格式可以看成是多个单帧图片的组合,从GIF图中提取每一帧图片,和静态图混合,最终再将混合后的n张图片组合成GIF。


在实际操作中,涉及到GIF的格式,GIF的拆分,图片混合,真彩色转256色,图片效果优化,GIF组合等。


首先介绍下GIF的格式


GIF图象是基于颜色列表的(存储的数据是该点的颜色对应于颜色列表的索引值),最多只支持8位(256色)。GIF文件内部分成许多存储块,用来存储多幅图象或者是决定图象表现行为的控制块,用以实现动画和交互式应用。GIF文件还通过GIF-LZW压缩算法压缩图象数据来减少图象尺寸。


GIF图像格式



大致分为三部分:文件头、GIF数据流、文件结尾

1.文件头

1.1GIF署名:由三个字节组成,固定为G、I、F,表示这是一张GIF图

1.2版本号:由三个字节组成,值为87a或89a。89a版本增加了一些扩展块,现在使用的GIF是89a版本


2.文件结尾

2.1文件终结器:1个字节,固定值0x3b,标识GIF图结束。


3.GIF数据流

这是最大的一块,描述了GIF的全局信息,以及每一帧GIF的信息

3.1控制块

3.1.1逻辑屏幕标识符

共7个字节,记录一些全局的信息。

wWidthGIF图像宽度,2Byte

wDepthGIF图像高度,2Byte

Globalflag1Byte

7

6

5

4

3

2

1

0

GlobalPal 

ColorRes

SortFlag  

PalBits

是否有全局调色板

ColorRes+1表示色彩深度

全局调色板中的RGB颜色值是否按照使用率进行从高到底的 次序排序的

全局调色板的位数

byBackground1Byte逻辑屏幕的背景颜色,画布颜色。当图像长宽小于逻辑屏幕的大小 时,未被图像覆盖部分的颜色值由该值对应的全局调色板中的索引颜色值确定。如果没有全局调色板,该值无效,默认背景颜色为黑色。

byAspect: 1Byte,逻辑屏幕的像素的长宽比例。

3.1.2全局颜色列表

如果有它的话(是否有由逻辑屏幕标识符中的Globalflag的最高bit位GlobalPal决定),必须紧跟在逻辑屏幕标识符后面,每个颜色列表索引条目由三个字节组成,按RGB的顺序排列。全局颜色列表的Size = 3 * 2 ^ (Globalflag & 0x07 + 1)


3.2图像块

图像块开始就是每一帧的信息了,包括每一帧的控制信息、数据信息、扩展信息(89a版本才有扩展信息)

3.2.1图形控制扩展

这是一个扩展块,89a版本才有的,也是89a版本加入的四个扩展块中最重要的一个,其他三个可以忽略了。

这个扩展块可以有也可以没有,如果有,一般是放在每一个图像块的开头,即图像标识符之前,用来控制跟在它后面的第一个图象的渲染形式。它有8个字节组成:

1字节

扩展块标识

固定值0x21

2字节

图形控制扩展标签

固定值0xF9

3字节

块大小

固定值4,说明之后4个字节的数据是当前扩展块的有效数据

4字节0bit

是否有透明性

如果该位为1,表明图像有透明属性,透明色颜色由参数byTransparencyIndex指定。

4字节1bit

是否有用户输入

如果该位为1,则表示在显示一副图像后,需要用户输入再进行下一个动作。

4字节2~4bit

图像 显示后的处理方式

0 - 不使用处置方法
                  1 - 不处置图形,把图形从当前位置移去
                     2 - 回复到背景色                      3 - 回复到先前状态
                    4-7 - 自定义

4字节5~7bit

保留

56字节

帧间隔时间

单位10ms

7字节

透明色索引值

8字节

当前扩展块终结标识

固定为0


3.2.2图像标识符

标识一帧图像的信息,由0x2C这个开始位标识它的开始,连开始标识位一共10个字节。(解析的时候读到0x2c说名接下来的10个字节就是图像标识符啦)

wLeft:2Byte图像相对逻辑屏幕左上角的X偏移像素
wTop:2Byte图像相对逻辑屏幕左上角的Y偏移像素
wWidth:2Byte图像的宽度
wDepth:2Byte图像的高度

Gifimage:1Byte,局部颜色列表标志

7

6

5

4

3

2

1

0

LocalPal  

Interlace 

SortFlag  

Reserved  

PalBits

是否有局部调色板

置位时图象数据使用交织方式排列

如果置位表示紧跟着的局部颜色列表分类排列

保留为,暂时无用

局部调色板的位数


3.2.3局部颜色列表

    如果上面的局部颜色列表标志置位的话,则需要在这里(紧跟在图象标识符之后)定义一个局部颜色列表以供紧接着它的图象使用。注意使用前应先保存原来的颜色列表,使用结束之后回复原来保存的全局颜色列表。如果一个GIF文件即没有提供全局颜色列表,也没有提供局部颜色列表,可以自己创建一个颜色列表,或使用系统的颜色列表。局部颜色列表的排列方式和全局颜色列表一样:RGBRGB......

3.2.4基于颜色列表的图象数据

图像压缩数据是按照GIF-LZW压缩编码后存储的。GIF-LZW编码是一种经过改良的LZW编码方式,它是一种无损压缩的编码方法。GIF-LZW编码方法是将原始数据中的重复字符串建立一个字符串表,然后用该重复字符串在字符串表中的索引来替代原始数据以达到压缩的目的。由于GIF-LZW压缩编码的需要,必须首先存储GIF-LZW的最小编码长度以供解码程序使用,然后再存储编码后的图像数据。编码后的图像数据是一个个数据子块的方式存储的,每个数据子块的最大长度为256字节。数据子块的第一个字节指定该数据子块的长度,接下来的数据为数据子块的内容。如果某个数据子块的第一个字节数值为0,即该数据子块中没有包含任何有用数据,则该子块称 为块终结符,用来标识数据子块到此结束。

最小编码长度

子块长度

数据块1

数据

......

子块长度

数据块n

数据


3.2.5注释扩展

89a版本可选。可以用来记录图形、版权、描述等任何的非图形和控制的纯文本数据(7-bit ASCII字符),注释扩展并不影响对图象数据流的处理,解码器完全可以忽略它。存放位置可以是数据流的任何地方,最好不要妨碍控制和数据块,推荐放在数据流的开始或结尾。

1字节

扩展块标识

固定值0x21

2字节

注释扩展标签

固定值0xFE

3字节开始

注释块

一个或多个数据块

n字节

注释扩展块结束标识

固定为0


3.2.6图形文本扩展

89a版本可选。这一部分是可选的(需要89a版本),用来绘制一个简单的文本图象,这一部分由用来绘制的纯文本数据(7-bit ASCII字符)和控制绘制的参数等组成。绘制文本借助于一个文本框(Text Grid)来定义边界,在文本框中划分多个单元格,每个字符占用一个单元,绘制时按从左到右、从上到下的顺序依次进行,直到最后一个字符或者占满整个文本框(之后的字符将被忽略,因此定义文本框的大小时应该注意到是否可以容纳整个文本),绘制文本的颜色索引使用全局颜色列表,没有则可以使用一个已经保存的前一个颜色列表。另外,图形文本扩展块也属于图形块(Graphic Rendering Block),可以在它前面定义图形控制扩展对它的表现形式进一步修改。图形文本扩展的组成:

              

1字节

扩展块标识

固定值0x21

2字节

图形控制扩展标签

固定值0x01

3字节

块大小

固定值12,说明之后12个字节的数据是当前扩展块的有效数据

45字节

文本框左边界位置

文本框离逻辑屏幕的左边界距离

67字节

文本框上边界位置

文本框离逻辑屏幕的上边界距离

89字节

文本框高度

1011字节

文本框宽度

12字节

文本单元格宽度

单个单元格宽度

13字节

文本单元格高度

单个单元格高度

14字节

文本前景色索引

15字节

文本背景色索引

16字节开始

文本数据块

要显示的字符串

n字节

注释扩展块结束标识

固定为0



推荐:

1、由于文本的字体(Font)和尺寸(Size)没有定义,解码器应该根据情况选择最合适的。
2、如果一个字符的值小于0x20或大于0xF7,则这个字符被推荐显示为一个空格(0x20)

3、为了兼容性,最好定义字符单元格的大小为8x88x16(宽度x高度)。

3.2.7应用程序扩展

89a版本可选。这是提供给应用程序自己使用的,应用程序可以在这里定义自己的标识、信息等。

1字节

扩展块标识

固定值0x21

2字节

图形控制扩展标签

固定值0xFF

3字节

块大小

固定值11,说明之后11个字节的数据是当前扩展块的有效数据

4~11字节

应用程序标识符

鉴别应用程序自身的表示

12~14字节

鉴别码

应用程序定义的特殊标识码

15字节开始

应用程序数据块

一个或多个数据块组成,保存应用程序自己定义的数据

n字节

注释扩展块结束标识

固定为0



从上面的GIF图片格式可以了解到,GIF的基本格式是全局信息+每帧图像的信息,帧之间的时间间隔可以从每帧的图形控制扩展中获得。因此,拆分GIF、合并GIF都是不困难的。

此外,GIF和单帧GIF的色深都是8位,最多支持256中颜色,采用调色板+索引的方式记录每个像素的颜色值,单帧GIF支持透明(图形控制扩展中标识)。

基于单帧GIF的透明属性,可以实现图片叠加效果:

先建立一张新的画板,在画板上画静态图,再画单帧的GIF,这样基于透明属性,就可以将一部分静态图透过来。

但是因为GIF是8位的,而现在的大部分常见图是24位的,那么在叠加并生成最终的GIF时,必然需要将24位(2^24种颜色)降为8位(2^8种颜色)。这个过程中色彩空间的减小将导致色彩丢失,因此需要采用一些处理手段尽可能的提升图片质量。


发布了56 篇原创文章 · 获赞 21 · 访问量 26万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览