| 
				 表2  文件头数据块的结构 
| 
 名称  | 
 字节数  | 
 说明  |  
| 
 Width (宽度)  | 
 4  | 
 图像宽度(单位:像素,0为无效值)   |  
| 
 Height (长度)  | 
 4  | 
 图像高度(单位:像素,0为无效值)  |  
| 
 Bit depth (图像深度)  | 
 1  | 
 索引彩色图像:1,2,4或8 灰度图像:1,2,4,8或16 真彩色图像:8或16  |  
| 
 Color type (颜色类型)  | 
 1  | 
 0:灰度图像, 2:真彩色图像 3:索引彩色图像 4:带α通道数据的灰度图像 
6:带α通道数据的真彩色图像  |  
| 
 Compression method (压缩方法)  | 
 1  | 
 显示所用压缩方法,国际标准中只定义了一种方法(method 0)  |  
| 
 Filter method (滤波器方法)  | 
 1  | 
 滤波器方法  |  
| 
 Interlace method (隔行扫描方法)  | 
 1  | 
 0:非隔行扫描;1: Adam7(由Adam M. Costello开发的7遍隔行扫描方法  |    
三、PNG类设计 
这一小节我们设计一个名为MyPNG的类,主要功能包括(1)将一幅PNG图像文件读入内存,对应函数为PngLoadImage (const char *pstrFileName);(2)将内存中的图像数据保存为PNG图像,对应函数为PngSaveImage (const char *pstrFileName);(3)显示PNG图像,对应函数为Draw( CDC *pDC, int nX = 0, int nY = 0, int nWidth = -1, int nHeight = -1 )。通常,Window应用程序中的其他格式的图像显示可通过显示其对应位图实现。由于PNG图像数据的存放格式与位图格式不同,因此为了显示PNG图像,需要将PNG图像数据转换成对应的位图格式数据,类中的成员函数PngToBitmap()就是实现这个功能。此外,显示位图像素数据时,需要知道位图文件信息,因此要将PNG图像的信息(如宽度、高度等)转换成相应位图文件信息,实现该功能的类成员函数为FillBitmapInfo()。于是,可得到MyPNG类的头文件定义: 
#ifndef _PNG_INC_ 
#define _PNG_INC_ 
#include "png.h"  //声明libpng库函数、png相关的结构体等信息的头文件 
class MyPNG 
{ 
public: 
        MyPNG(); 
  ~MyPNG();    
  bool PngToBitmap();     //将Png数据区转换到bitmap数据区 
   bool FillBitmapInfo(); 
  BOOL Draw( CDC *pDC, int nX = 0, int nY = 0, int nWidth = -1, int nHeight = -1 ); //显示位图 
   BOOL PngLoadImage (const char *pstrFileName);  //载入PNG 
   BOOL PngSaveImage (const char *pstrFileName);  //将pPixelBuffer的数据保存PNG 
public: 
  png_structp png_ptr;    //libpng定义的结构体指针,存放用于读/写png图像的信息 
  png_infop info_ptr;     // libpng定义的结构体指针,存放png文件信息 
png_byte  *pbImage; //存放次序是R-G-B 
//PNG图像数据,该数据存放规则与位图相反(第一个像素在左下角,自下而上,从左到右),即第一个像素在左上角(自上而下,从左到右存放) 
    int  cxImgSize, cyImgSize; //图像宽度、高度 
    int  cImgChannels;       //颜色通道 
//图像深度,索引彩色图像:1,2,4或8;灰度图像:1,2,4,8或16;真彩色图像:8或16 
    int  iBitDepth; 
int  iColorType;   //颜色类型,0 --灰度图像,2--真彩色图像,3--索引彩色图像,4--带α通道数据的灰度图像 
               //6--带α通道数据的真彩色图像 
    png_color   bkgColor;      //背景颜色 
BITMAPINFO m_bmi;      //位图文件信息 
  BYTE   *pPixelBuffer;   //存放PNG的位图数据缓存区 
    WORD  wImgRowBytes;   //每行的字节数 
}; 
#endif 
下面是类成员函数的详细定义。类的构造函数用来初始化成员变量信息,析构函数的作用是释放内存空间。 
MyPNG::MyPNG() 
{ png_ptr=NULL; info_ptr=NULL;  pbImage=NULL; pPixelBuffer=NULL; 
     bkgColor.red=127; bkgColor.green=127; bkgColor.blue=127;   cxImgSize=0; cyImgSize=0; wImgRowBytes=0; 
} 
MyPNG::~MyPNG() 
{ if (pbImage!=NULL) free(pbImage); if (png_ptr!=NULL) free(png_ptr); 
     if (info_ptr!=NULL) free(info_ptr);    if (pPixelBuffer!=NULL) delete pPixelBuffer; 
} 
成员函数PngLoadImage从路径pstrFileName读入PNG图像,并将PNG图像数据转换成位图数据,设置位图信息。如果执行函数成功,返回TRUE,失败则返回FALSE。函数中使用了一个例外处理的宏定义,Try{} Catch(){};其详细定义在另外一个头文件cexcept.h (libpng例程visupng有该文件定义),这里不再列举。 
BOOL MyPNG::PngLoadImage (const char *pstrFileName)  
{   FILE  *pfFile;  png_byte  pbSig[8]; 
    double  dGamma;   int  i; 
    png_color_16   *pBackground;  png_uint_32  ulChannels, ulRowBytes; 
    static png_byte  **ppbRowPointers = NULL; 
    if (!pstrFileName)  {pbImage=NULL;  return FALSE; } //文件名指针为空则返回 
    if (!(pfFile = fopen(pstrFileName, "rb")))  { pbImage=NULL; return FALSE; } //打开PNG文件 
    fread(pbSig, 1, 8, pfFile); //读取8位PNG文件署名 
    if (!png_check_sig(pbSig, 8))  {  pbImage=NULL; return FALSE;  } //检查PNG文件署名 
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, 
         (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL); //创建结构体信息 
    if (!png_ptr) {pbImage=NULL; return FALSE;} //创建失败,返回 
    info_ptr = png_create_info_struct(png_ptr); //创建结构体 
//创建失败,释放已创建信息,返回false 			
				 |