欢迎查看系列博客:html
《PNG文件格式》(一)PNG文件概述 《PNG文件格式》(二)PNG文件格式分析(本篇)算法
摘自:spa
中文PNG格式说明:dev.gameres.com.net
PNG文件格式白皮书:www.w3.org3d
LZ77算法的JAVA实现:jazzlib.sourceforge.net
LZ77算法的JAVA实现,包括J2ME版本:www.jcraft.comorm
===============================正文=======================================
htm
对于一个PNG文件来讲,其文件头老是由位固定的字节来描述的,HEX: 89 50 4E 47 0D 0A 1A 0Ablog
使用ultra打开一个png图片,结果以下:索引
其中第一个字节0x89超出了ASCII字符的范围,这是为了不某些软件将PNG文件当作文本文件来处理。文件中剩余的部分由3个以上的PNG的数据块(Chunk)按照特定的顺序组成,所以,一个标准的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 | 图像结束数据 | 否 | 否 | 最后一个数据块 |
名称 | 字节数 | 说明 |
Length (长度) | 4字节 | 指定数据块中数据域的长度,其长度不超过(231-1)字节 |
Chunk Type Code (数据块类型码) | 4字节 | 数据块类型码由ASCII字母(A-Z和a-z)组成 |
Chunk Data (数据块数据) | 可变长度 | 存储按照Chunk Type Code指定的数据 |
CRC (循环冗余检测) | 4字节 | 存储用来检测是否有错误的循环冗余码 |
注意:Length值的是除:length自己,Chunk Type Code,CRC外的长度,也就是Chunk Data的长度。
下面,咱们依次来了解一下各个【关键数据块】的结构
域的名称
|
字节数
|
说明
|
Width | 4 bytes | 图像宽度,以像素为单位 |
Height | 4 bytes | 图像高度,以像素为单位 |
Bit depth | 1 byte | 图像深度: 索引彩色图像:1,2,4或8 灰度图像:1,2,4,8或16 真彩色图像:8或16 |
ColorType | 1 byte | 颜色类型: 0:灰度图像, 1,2,4,8或16 2:真彩色图像,8或16 3:索引彩色图像,1,2,4或8 4:带α通道数据的灰度图像,8或16 6:带α通道数据的真彩色图像,8或16 |
Compression method | 1 byte | 压缩方法(LZ77派生算法) |
Filter method | 1 byte | 滤波器方法 |
Interlace method | 1 byte | 隔行扫描方法: 0:非隔行扫描 1: Adam7(由Adam M. Costello开发的7遍隔行扫描方法) |
因为咱们研究的是手机上的PNG,所以,首先咱们看看MIDP1.0对所使用PNG图片的要求吧:
● 在MIDP1.0中,咱们只可使用1.0版本的PNG图片。而且,因此的PNG关键数据块都有特别要求:
IHDR
● 文件大小:MIDP支持任意大小的PNG图片,然而,实际上,若是一个图片过大,会因为内存耗尽而没法读取。
● 颜色类型:全部颜色类型都有被支持,虽然这些颜色的显示依赖于实际设备的显示能力。同时,MIDP也能支持alpha通道,可是,全部的alpha通道信息都会被忽略而且看成不透明的颜色对待。
● 色深:全部的色深都能被支持。
● 压缩方法:仅支持压缩方式0(deflate压缩方式),这和jar文件的压缩方式彻底相同,因此,PNG图片数据的解压和jar文件的解压可使用相同的代码。(其实这也就是为何J2ME能很好的支持PNG图像的缘由:))
● 滤波器方法:尽管在PNG的白皮书中仅定义了方法0,然而全部的5种方法都被支持!
● 隔行扫描:虽然MIDP支持0、1两种方式,然而,当使用隔行扫描时,MIDP却不会真正的使用隔行扫描方式来显示。
● PLTE chunk:支持
● IDAT chunk:图像信息必须使用5种过滤方式中的方式0 (None, Sub, Up, Average, Paeth)
● IEND chunk:当IEND数据块被找到时,这个PNG图像才认为是合法的PNG图像。
● 可选数据块:MIDP能够支持下列辅助数据块,然而,这却不是必须的。
bKGD cHRM gAMA hIST iCCP iTXt pHYs
sBIT sPLT sRGB tEXt tIME tRNS zTXt
关于更多的信息,能够参考www.w3.org
物理像素数据块,它表示了图片的像素尺寸,或者是高宽比,它的结果以下
Pixels per unit, X axis | 4 bytes (PNG unsigned integer) |
Pixels per unit, Y axis | 4 bytes (PNG unsigned integer) |
Unit specifier | 1 byte |
0 | unit is unknown |
1 | unit is the metre |
颜色 |
字节 |
意义 |
Red |
1 byte |
0 = 黑色, 255 = 红 |
Green |
1 byte |
0 = 黑色, 255 = 绿色 |
Blue |
1 byte |
0 = 黑色, 255 = 蓝色 |
不难理解,因为数据块结构的定义,IEND数据块的长度老是0(00 00 00 00,除非人为加入信息),数据标识老是IEND(49 45 4E 44),所以,CRC码也老是AE 42 60 82。
IHDR cHRM pHYs IEND