PNG文件结构分析(上:了解PNG文件存储格式)
前言
我们都知道,在进行J2ME的手机应用程序开发的时候,在图片的使用上,我们能够使用PNG格式的图片(甚至于在有的手机上,我们仅仅能够使用PNG格式的图片),虽然使用图片能够为我们的应用程序添加不少亮点,然而,仅仅支持PNG格式的图片却又限制了我们进一步发挥的可能性(事实上,应该说是因为手机平台上的处理能力有限)。 在MIDP2中,或者某些厂商(如NOKIA)提供的API中,提供了drawPixels/getPixels的方法,这些方法进一步提高了开发人员处理图片的灵活性,然而,在MIDP2还未全然普及的今天,我们须要在MIDP1 .0中实现这类方法还属于异想天开,因此,为了实现更高级的应用,我们必须充分挖掘PNG的潜力。
PNG的文件结构
对于一个PNG文件来说,其文件头总是由位固定的字节来描写叙述的:
十进制数 | 137 80 78 71 13 10 26 10 |
十六进制数 | 89 50 4E 47 0D 0A 1A 0A |
当中第一个字节0x89超出了ASCII字符的范围,这是为了避免某些软件将PNG文件当做文本文件来处理。文件里剩余的部分由3个以上的PNG的数据块(Chunk)依照特定的顺序组成,因此,一个标准的PNG文件结构应该例如以下:
PNG文件标志 | PNG数据块 | …… | PNG数据块 |
PNG数据块(Chunk)
PNG定义了两种类型的数据块,一种是称为重要数据块(critical chunk),这是标准的数据块,还有一种叫做辅助数据块(ancillary chunks),这是可选的数据块。重要数据块定义了4个标准数据块,每一个PNG文件都必须包括它们,PNG读写软件也都必需要支持这些数据块。尽管PNG文件规范没有要求PNG编译码器对可选数据块进行编码和译码,但规范提倡支持可选数据块。
下表就是PNG中数据块的类别,当中,重要数据块部分我们使用深色背景加以区分。
PNG文件格式中的数据块 | ||||
数据块符号 | 数据块名称 | 多数据块 | 可选否 | 位置限制 |
IHDR | 文件头数据块 | 否 | 否 | 第一块 |
cHRM | 基色和白色点数据块 | 否 | 是 | 在PLTE和IDAT之前 |
gAMA | 图像γ数据块 | 否 | 是 | 在PLTE和IDAT之前 |
sBIT | 样本有效位数据块 | 否 | 是 | 在PLTE和IDAT之前 |
PLTE | 调色板数据块 | 否 | 是 | 在IDAT之前 |
bKGD | 背景颜色数据块 | 否 | 是 | 在PLTE之后IDAT之前 |
hIST | 图像直方图数据块 | 否 | 是 | 在PLTE之后IDAT之前 |
tRNS | 图像透明数据块 | 否 | 是 | 在PLTE之后IDAT之前 |
oFFs | (专用公共数据块) | 否 | 是 | 在IDAT之前 |
pHYs | 物理像素尺寸数据块 | 否 | 是 | 在IDAT之前 |
sCAL | (专用公共数据块) | 否 | 是 | 在IDAT之前 |
IDAT | 图像数据块 | 是 | 否 | 与其它IDAT连续 |
tIME | 图像最后改动时间数据块 | 否 | 是 | 无限制 |
tEXt | 文本信息数据块 | 是 | 是 | 无限制 |
zTXt | 压缩文本数据块 | 是 | 是 | 无限制 |
fRAc | (专用公共数据块) | 是 | 是 | 无限制 |
gIFg | (专用公共数据块) | 是 | 是 | 无限制 |
gIFt | (专用公共数据块) | 是 | 是 | 无限制 |
gIFx | (专用公共数据块) | 是 | 是 | 无限制 |
IEND | 图像结束数据 | 否 | 否 | 最后一个数据块 |
为了简单起见,我们如果在我们使用的PNG文件里,这4个数据块按以上先后顺序进行存储,而且都仅仅出现一次。
数据块结构
PNG文件里,每一个数据块由4个部分组成,例如以下:
名称 | 字节数 | 说明 |
Length (长度) | 4字节 | 指定数据块中数据域的长度,其长度不超过(231-1)字节 |
Chunk Type Code (数据块类型码) | 4字节 | 数据块类型码由ASCII字母(A-Z和a-z)组成 |
Chunk Data (数据块数据) |