PNG文件结构分析之一(了解PNG文件存储格式) |
||||||||||||
| 作者:leftmoon 来源:J2MEDV 发布时间:2005-9-7 13:04:01 | ||||||||||||
|
Up, Average, Paeth)
关于更多的信息,可以参考http://www.w3.org/TR/REC-png.html PLTE 调色板数据块PLTE(palette chunk)包含有与索引彩色图像(indexed-color image)相关的彩色变换数据,它仅与索引彩色图像有关,而且要放在图像数据块(image data chunk)之前。 PLTE数据块是定义图像的调色板信息,PLTE可以包含1~256个调色板信息,每一个调色板信息由3个字节组成:
因此,调色板的长度应该是3的倍数,否则,这将是一个非法的调色板。 对于索引图像,调色板信息是必须的,调色板的颜色索引从0开始编号,然后是1、2……,调色板的颜色数不能超过色深中规定的颜色数(如图像色深为4的时候,调色板中的颜色数不可以超过2^4=16),否则,这将导致PNG图像不合法。 真彩色图像和带α通道数据的真彩色图像也可以有调色板数据块,目的是便于非真彩色显示程序用它来量化图像数据,从而显示该图像。 IDAT 图像数据块IDAT(image data chunk):它存储实际的数据,在数据流中可包含多个连续顺序的图像数据块。 IDAT存放着图像真正的数据信息,因此,如果能够了解IDAT的结构,我们就可以很方便的生成PNG图像。 IEND 图像结束数据IEND(image trailer chunk):它用来标记PNG文件或者数据流已经结束,并且必须要放在文件的尾部。 如果我们仔细观察PNG文件,我们会发现,文件的结尾12个字符看起来总应该是这样的: 00 00 00 00 49 45 4E 44 AE 42 60 82 不难明白,由于数据块结构的定义,IEND数据块的长度总是0(00 00 00 00,除非人为加入信息),数据标识总是IEND(49 45 4E 44),因此,CRC码也总是AE 42 60 82。 实例研究PNG 以下是由Fireworks生成的一幅图像,图像大小为8*8,
可以看到,选中的头8个字节即为PNG文件的标识。 接下来的地方就是IHDR数据块了: 00000008~00000020:
00000021~0000002F:
可选数据块sBIT,颜色采样率,RGB都是256(2^8=256) 00000030~00000062:
这里是调色板信息
00000063~000000C5:
这部分包含了pHYs、tExt两种类型的数据块共3块,由于并不太重要,因此也不再详细描述了。
以上选中部分是IDAT数据块
IDAT中压缩数据部分在后面会有详细的介绍。 000000F9~00000104:
IEND数据块,这部分正如上所说,通常都应该是 00 00 00 00 49 45 4E 44 AE 42 60 82 至此,我们已经能够从一个PNG文件中识别出各个数据块了。由于PNG中规定除关键数据块外,其它的辅助数据块都为可选部分,因此,有了这个标准后,我们可以通过删除所有的辅助数据块来减少PNG文件的大小。(当然,需要注意的是,PNG格式可以保存图像中的层、文字等信息,一旦删除了这些辅助数据块后,图像将失去原来的可编辑性。)
删除了辅助数据块后的PNG文件,现在文件大小为147字节,原文件大小为261字节,文件大小减少后,并不影响图像的内容。 其实,我们可以通过改变调色板的色值来完成一些又趣的事情,比如说实现云彩/水波的流动效果,实现图像的淡入淡出效果等等,在此,给出一个链接给大家看也许更直接:http://blog.csdn.net/flyingghost/archive/2005/01/13/251110.aspx,我写此文也就是受此文的启发的。 如上说过,IDAT数据块是使用了LZ77压缩算法生成的,由于受限于手机处理器的能力,因此,如果我们在生成IDAT数据块时仍然使用LZ77压缩算法,将会使效率大打折扣,因此,为了效率,只能使用无压缩的LZ77算法,关于LZ77算法的具体实现,此文不打算深究,如果你对LZ77算法的JAVA实现有兴趣,可以参考以下两个站点:
参考资料: PNG文件格式白皮书:http://www.w3.org/TR/REC-png.html |
||||||||||||
| [] [返回上一页] [打 印] | ||||||||||||
|
||||||||||||
文章评论 |
||||||||||||

为了方便大家观看,我们将图像放大:







