摘 要 运用libpng库函数,设计了一个可读写PNG格式图像的C++类。同时,在VC++6.0开发平台下,设计出一个基于多文档结构的图像浏览器,实现PNG格式图像的读写及显示。
关键词 PNG, 图像格式,C++,类
一、前言
PNG是一种可携式网络图像格式(Portable Network Graphic Format,PNG),其名称来源于非官方的“PNG's Not GIF”,是一种位图文件(Bitmap file)存储格式,读成“ping”[1]。在20世纪90年代, GIF已经普遍使用,然而在1995年新年前后,Unisys 和CompuServe两家公司突然宣布编程使用GIF均需要向其支付版税,理由是他们拥有LZW压缩算法(GIF格式采用该算法)的版权。付费问题,迫使众多开发人员设计和开发新的用以代替GIF的图像格式。PNG出现的初衷就是为了替代GIF文件格式,避免支付版税。因此,设计PNG时,保留了GIF的众多特性,如(1)使用彩色查找表(也称调色板)可支持256种颜色的彩色图像;(2)流式读/写性能(Streamability);(3)逐次逼近显示(Progressive display);(4)透明性(Transparency);(5)使用无损压缩等。同时,也增加了一些GIF文件格式所不具备的特性,如(1)每个像素为48位的真彩色图像;(2)每个像素为16位的灰度图像;(3)可为灰度图和真彩色图添加α通道;(4)添加图像的γ信息;(5)使用循环冗余码(Cyclic redundancy code,CRC)检测损害的文件;(6)加快图像显示的逐次逼近显示方式;(7)标准的读/写工具包等。目前,PNG已成为国际互网络联盟(World Wide Web Consortium ,W3C)推荐的标准[2],是互联网中常用的图像格式之一,常见的绘图软件和浏览器均支持PNG图像浏览(其中IE 4.0以上版本均支持PNG)。本文利用http://www.libpng.org提供的libpng库[3],设计一个可读写PNG图像的C++类,同时利用VC++6.0开发平台,通过PNG图像浏览器的实例设计,说明PNG类的使用方法。
二、PNG文件结构
PNG图像由一个8字节的PNG文件署名(PNG file signature)域和按照特定结构组织的3个以上的数据块(Chunk)组成。PNG文件署名域是用来识别该文件是不是PNG文件,如果用十进制数表示,该域的值依此是137, 80, 78, 71, 13, 10, 26, 10,(对应的十六进制数为 89,50,4e,47,0d, 0a,1a,0a)。PNG数据块由表1所示的4个域构成[2]。根据类型的不同,PNG数据块又可分为两种:一种是关键数据块(Critical chunk),这是标准的数据块,另一种叫做辅助数据块(Ancillary chunks),是可选的数据块。其中,关键数据块又定义了4个标准数据块,分别为(1)文件头数据块IHDR(Header chunk);(2)调色板数据块PLTE(Palette chunk);(3)图像数据块IDAT(Image data chunk);(4)图像结束数据IEND(Image trailer chunk)。由于篇幅限制,这里只介绍与编程设计最为密切的文件头数据块结构,具体见表2,其他数据块格式可参考文献[2]。
表1 PNG数据块的结构
名称 |
字节数 |
说明 |
Length(长度) |
4 |
指定数据块中数据域的长度,其长度不超过(231-1)字节 |
Chunk Type Code(数据块类型码) |
4 |
数据块类型码由ASCII字母(A-Z和a-z)组成 |
Chunk Data(数据块数据) |
可变长度 |
存储按照Chunk Type Code指定的数据 |
CRC(循环冗余检测) |
4 |
存储用来检测是否有错误的循环冗余码 |
|