认识PNG (一)

Png是一种图形文件的存储格式 portable network graphics(可移植性网络图形)的缩写,读成“ping”(来自百度百科)。Png文件格式是网络上广泛使用的应用格式。

 

PNG是我们在前端开发中使用的比较多的一种图像文件格式,这种文件的最初的设计的目的就是为了替代gif(专利问题)和tiff(标签图像文件格式Tagged Image File Format,平常接触的比较少,主要用在图像处理应用、比如QuarkXPress和Adobe InDesign的桌面印刷、页面排版应用,扫描、传真、文字处理、光学字符识别,目前Adobe控制它的规范)。

 

特性:

 

因为是针对替代gif和tiff而设计的,所以的他的特点也是显而易见的,额,没有专利纠纷,格式相对简单,体积小能够保持较丰富的画质,完全针对于当时较慢的互联网设计的,有保留了gif和tiff的一些优点。那么他有那些具体的特点呢:

  1. 支持256色调色板
  2. 支持datastream,图像文件格式允许连续读出和写入图像数据,这个特性很适合在通信过程中使用。
  3. 逐次逼近显示,这种特性可使在网络传输过程中可以显示模糊的图像,然后逐步显示图像细节。
  4. 透明效果
  5. 辅助数据块
  6. 无损压缩,体积小。
  7. 独立于计算机软硬件环境
  8. 索引彩色模式
  9. 每个像素为48位的真彩色图像。
  10. 每个像素为16位的灰度图像。
  11. 可为灰度图和真彩色图添加α通道。
  12. 添加图像的γ信息

文件存储结构

1 png-8和png-24

在我们平常的切片中会遇到png-8 和 png-24两种格式的png,那么这种有什么区别呢?其最大的区别是PNG-24是用24位(bit)来保存一个像素值,是真彩色,而PNG-8是用8位(bit)索引值来在调色板中索引一个颜色,因为一个索引值的最大上限为2的8次方既256,故调色板中颜色数最多为256种。

其实PNG有5中类型:灰度,真彩色,索引色,带alpha通道的灰度,带alpha通道的真彩色。

 

在ps可以直观的看到调色板的原理:

 

 

2 文件存储结构

 

 

2.1 存储结构

如上图。

Png文件总体上分两部分,文件标示和数据块(chunks)。

关键数据块一个png文件必须有的结构,而辅助数据块存储一些附加信息,不是必须的的。正是因为这一点,很多游戏在优化时,去除游戏资源包中的PNG图片的辅助数据块就是一个很不错的方法。

 

需要注意的一点是:PNG图像格式使用Big-Endian顺序存储数据,网络字节序,也就是在内存结构中,高位字节和低位字节是顺序排列的(虽然按照地址老说,高位字节在低位地址)。这点是看明白pnglib中read png的一个基础。

 

2.2 PNG文件标示

所有的png文件开头都有相同的标示(signature),固定的8个字节:

 对应的ASCI码是,这个8个字节的出现标示下面的数据是由IHDR数据块开始以IEND数据结束的PNG数据流。

 

2.3 数据块结构

紧跟在文件标示后面的就是图像数据块。图像数据块(chunk)有很多类型,分为关键数据块(critical chunk)和辅助数据块(ancillary chunk)两大类。关键数据块是PNG文件必须的,辅助数据块是可选的。所有数据块都有相同的结构,如下图:

 

 

 

 

 

 

 

 

 

字 段 名

size(单

位:字节)

描   述

Length(长度)

4(无符号)

Chunk Data的数据长度 ,不包括Length 、Chunk Type Code、

CRC。

Chunk Type Code

(数据块类型字符)

4

数据块类型,例如

IHDR、PLTE、IDAT等。这里需要注意的是chunk type的命名是由规范。(对自由扩展的PNG开发者来说需要仔细理解)

Chunk Data(数据块数据)

Length|0

图像数据

CRC(循环冗余检测)

4

循环冗余码(ISO 3309)(计算的是 chunk type code+chunk data)

 

示例:

 

 

关键数据块包括:文件头数据块(IHDR),调色板(PLTE),图像数据块(IDAT),图像结束数据块(IEND),其中调色板在png-24是可选的。

 

 

 

 

数据块名称

说 明

允许多个

数据块

位   置

文件头数据块(IHDR)

 

不允许

第一个数据块

调色板数据块(PLTE)

 

不允许

第二个数据块,可选

图像数据块(IDAT)

Lw77变种压缩算法

允许

如果有调色板数据块(PLTE),则是第三个数据块,如果没有调色板数据块(PLTE),则时第二个数据块。如果有多个图像数据块,则必须按图像数据连续存储

图像结束数据(IEND)

 

不允许

最后一个数据块

         

 

 

辅助数据块相关说明:

数据块名称

说 明

允许多个

数据块

位   置

基色和白色点数据块(cHRM

色彩(空间)管理相关

不允许

在PLTE和IDAT之前

图像γ数据块(gAMA

 

不允许

在PLTE和IDAT之前

ICCP(iCCP)

 

允许

在PLTE之后IDAT之前如果有iCCP,则无sRGB

样本有效位数据块(sBIT

 

不允许

在PLTE和IDAT之前

标准RPG颜色(sRGB

 

不允许

在PLTE之后IDAT之前如

果有sRGB,则无iCCP

背景颜色数据块(bKGD

 

不允许

在PLTE之后IDAT之前

图像直方图数据块(hIST

 

不允许

在PLTE之后IDAT之前

图像透明数据块(tRNS

调色板中一个实体的透明度

不允许

在PLTE之后IDAT之前

物理像素尺寸数据块(pHYs

 

不允许

在IDAT之前

建议调色板(sPLT

 

允许

在IDAT之前

图像最后修改时间数据块(tIME

年月日时分秒(UTC)

不允许

无限制

国际文本数据(iTXt

 

允许

无限制

文本信息数据块(tEXt

 

允许

无限制

压缩文本数据块(zTXt

 

允许

无限制

         

辅助数据块有很多为了支持复杂的颜色空间管理很对调色板的扩展,比如cHRMsBIT等。它们在png文件的顺序是有一定规定的。和颜色管理相关的一般在PLTE之后IDAT之前。其他文本信息,比如tIME,tEXt则是无限制的,也就是可以和其他数据块任意顺序。

 

2.4 IHDR

它包含有PNG文件中存储的图像数据的基本信息,如图像的宽高、色深、颜色类型、压缩方式等。一个PNG文件只能有一个文件头数据块,下表列出了文件头数据块(IHDR)中各字段的含义。

字段名

大小(单

位:字节)

描   述

示    例

Width

4

图像宽度,以像素为单位

 

0x3c = 60px

Height

4

图像高度,以像素为单位

 

0x78 = 120px

Bit depth

1

图像深度:

索引彩色图像:1,2,4或8

灰度图像:1,2,4,8或16

真彩色图像:8或16

 

 

 

 

0x8 = 真彩色图像

ColorType

1

颜色类型:

0:灰度图像,1,2,4,8或16

2:真彩色图像,8或16

3:索引彩色图像,1,2,4或8

4:带α通道数据的灰度图像,8或16

6:带α通道数据的真彩色图像,8或16

 

0x06 =带α通道数据的真彩色图像

Compression

 method

1

压缩方法(LZ77变种算法)

 

Filter method

1

滤波器方法,png标准中定义了5中滤波器。

0:none(无过滤)

1:sub(当前值减去左侧像素的值)

2 :up(当前值减去上方像素的值)

3:average(减去左侧和上方像素的平均值)

4:paeth(替换上方,左边或者上方的左边像素值,并重新以Alan Paeth命名)

(后续研究)

 

Interlace

 method

1

隔行扫描方法:

0:非隔行扫描

1: Adam7(由Adam M.

 Costello开发的7遍隔行扫描方法)

 

2.5 调色板(PLET)

一个PNG文件只有一个调色板数据块。

调色板数据类似一个数组,每个元素包括btRed,btGreen,btBlue三个字段。

调色板的索引从0开始。

 

字段名

大小(单

位:字节)

描   述

btRed

1

红色颜色值

btGreen

1

绿色颜色值

btBlue

1

蓝色颜色值

 

 

 

 

 

 

 

调色板索引原理图:

 

 

 

 

 

2.6图像数据块(IDAT)

PNG的图像数据块(IDAT)存储图像的实际数据,存储的是图像数据,由于PNG可包含多幅图像,所以PNG的图像数据块可能是由一幅图像的数据组成,也可能是由多幅图像的数据组成。(gif也可以包括多幅图像)

图像数据块中的图像数据可能是经过变种的LZ77压缩编码DEFLATE压缩的。

(解压后的数据结构(data layout)需要继续研究。)

我们知道的图像是由像素组成,像素实际上是真实世界的色彩采样(sample)。图像数据中每个像素的色深和颜色分值的关系:

 

 

2.7 图像结束数据(IEND)

PNG的图像结束数据(IEND)用来标记PNG文件结束,并且必须要放在文件的尾部。和png文件标示是对应的,一个开始一个结尾。一般情况下,所有PNG图像结束数据(IEND)的十六进制数值都是一样的,具体的数值如下:

 

 

2.8贴吧中使用的PNG的包含的数据块(以frs/pb右侧我的应用-添加应用的背景图为例):

 

 

3 PNG应用

3.1 内存计算

图片在内存占用取决于图像的尺寸和像素位数。

 

对于一张100*100的png-24的图片,其内存占用 = 100*100*4 * 8 /8 bytes = 40000bytes = 39.0625 kb

3.2 Png文件的加载过程

一张100*100的png-24的图片为例,

 

  1. 读取图片文件(消耗图片大小内存,3.21k)    
  2. 解析PNG数据(编码后的内存大小如5.1计算为39k)
  3. 释放3.21k的图片内存(已经获得编码后的png)
  4. 渲染PNG (这个还需要验证)    
  5. 释放内存。     

注意,这个过程不是必然的顺序执行,释放内存的实际是有系统决定的,会很快,但是不一定是立即执行。  所以内存会瞬间飙升然后稳定。(需要验证)

 

3.3 CRC计算

CRC是循环冗余检测的缩写,因为这种算法简单易于硬件实现,一般用在数据通信的检测上,冗余码附加在信息码上,验证信息码是否有丢失。

在png中CRC计算的是数据块类型ChunkType和ChunkType。

 

这种算法需要一个生成多项式G(n),需要计算的数据多项式N(k)

一般的冗余码的位数是r=  n-1,

冗余码 R = (N(k)<<r)%G(n)

 

PNG使用生成多项式是:

 

=(1 0000 0100 1000 0001 0001 1001 1011 0101)

= 1 04 81 19 b3

 

 

 

4 PNG优化

4.1 去掉版本和联系信息(辅助数据块)

每张图片可以节省大概0.8k,(png,其他格式待研究)。

 贴吧首页43个png请求,大概可以节省流量43*0.8k = 34k

Frs(李毅) 49个png请求,大概可以节省流量49*0.8k = 39k

 

 

极端性的优化扫描每个png图片,去掉png-24所有的辅助数据块。(代码开发中)

 

也可以使用OptiPNG和pngcrush优化压缩。

 

从版权上来说,这个去掉月否有待商榷。

 

 

4.2 尽量减少单张png的高度和宽度

减少内存占用,提高机器渲染速度

 

 

去掉不必要的透明像素,如果png不使用过滤器也将会占用不必要的硬盘空间和流量。

 参考资料:

PNG技术标准:http://www.w3.org/TR/2003/REC-PNG-20031110/

Libpng:http://www.libpng.org/pub/png/libpng.html

关于DEFLATE详细介绍可以参考《DEFLATE Compressed Data Format Specification version 1.3》, http://www.ietf.org/rfc/rfc1951.txt

posted @ 2015-03-24 22:51  daoyuly  阅读(1202)  评论(0)    收藏  举报