前言
我们都知道,在进行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 (数据块数据)
可变长度
存储按照Chunk Type Code指定的数据
CRC (循环冗余检测)
4字节
存储用来检测是否有错误的循环冗余码
CRC(cyclic redundancy check)域中的值是对Chunk Type Code域和Chunk Data域中的数据进行计算得到的。CRC具体算法定义在ISO 3309和ITU-T V.42中,其值按下面的CRC码生成多项式进行计算:
x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1