| 
				 四、实例设计 
在设计实例前,先准备好相关的库。PNG文件的读写库为libpng,由于PNG用到LZ77派生压缩算法,因此,编译读写库时,libpng需要连接zlib库[4],这两个库的源代码可在文献[3]和文献[4]中获得。下面开始讲解如何应用VC++6.0设计PNG图像浏览器。 
第一步:建立一个名为PngImage的多文档框架应用程序,其View类选择继承于CScrollView。 
第二步:在应用程序CPngImageApp的初始化函数InitInstance()中,加入以下代码 
cmdInfo.m_nShellCommand=CCommandLineInfo::FileNothing; 
    该代码位于ParseCommandLine(cmdInfo)后,目的是使程序启动时,不打开新的空白文档。同时将字符串IDR_PNGIMATYPE修改为“\nPNG\nPNG\nPNG(*.png)\n.png\nPNG.Document\nPNG Document”,目的是打开文件时,默认的文件对话框只显示后缀名为PNG文件。 
第三步:从libpng库和zlib库中,选择以下文件,将他们添加到PngImage项目中。 
pngconf.h, png.h, libpng.lib, cexcept.h, zlib.lib, zlib.h, zconf.h 
同时,将第三节设计的MyPNG类也添加到项目中。 
第四步:为文档类CPngImageDoc添加公有成员变量 MyPNG m_png, 并改写OnOpenDocument函数,具体如下: 
BOOL CPngImageDoc::OnOpenDocument(LPCTSTR lpszPathName)  
{ if (!CDocument::OnOpenDocument(lpszPathName))  return FALSE; 
BOOL ret=m_png.PngLoadImage((const char *)lpszPathName); 
     return ret; 
} 
重写文档类的虚函数OnSaveDocument,具体如下: 
BOOL CPngImageDoc::OnSaveDocument(LPCTSTR lpszPathName)  
{  BOOL ret=m_png.PngSaveImage((const char *)lpszPathName); 
if (ret==TRUE)   AfxMessageBox("保存成功!"); 
else  AfxMessageBox("保存失败!"); 
      return ret; 
} 
  
同时,为菜单IDR_PNGIMATYPE中的“另存为”添加消息映射,具体代码如下: 
void CPngImageDoc::OnFileSaveAs()  
{ 
    BOOL ret; 
    static char BASED_CODE szSaveFilter[]="PNG(*.png)|*.png||";     //过滤文件 
    //创建文件保存对话框 
    CFileDialog FileDlg(FALSE,"*.png",NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szSaveFilter);   
    if (FileDlg.DoModal()==IDOK)    //如果选择确定按钮,则保存 
    {   ret=m_png.PngSaveImage((const char *)FileDlg.m_ofn.lpstrFile); 
        if (ret==TRUE)  AfxMessageBox("另存成功!"); 
        else    AfxMessageBox("另存失败!"); 
    } 
} 
第五步:修改视图类CPngImageView中的OnDraw()函数,具体如下: 
void CPngImageView::OnDraw(CDC* pDC) 
{    CPngImageDoc* pDoc = GetDocument();  
ASSERT_VALID(pDoc); 
     int w = pDoc->m_png.cxImgSize; //图像的宽度 
     int h = pDoc->m_png.cyImgSize; //图像的高度 
CSize sizeTotal(w, h);         
        CRect rcClient; 
GetClientRect(&rcClient);    //获取客户区的大小 
if (rcClient.Width()<sizeTotal.cx||rcClient.Height()<sizeTotal.cy) 
       { 
        SetScrollSizes(MM_TEXT, sizeTotal);  //设置滚动窗大小 
        GetParentFrame()->RecalcLayout(TRUE); // 
        ResizeParentToFit(); 
       } 
pDoc->m_png.Draw(pDC); //显示PNG图像对应的位图 
} 
至此,整个PNG图像浏览器已经设计完毕。编译程序并运行,点击浏览器的菜单“文件->打开”,可读入并显示PNG图像,如图1(a)所示。此时,点击菜单“文件->另存为”,将出现如图1(b)所示的窗口,在对话框中输入文件名,即可将当前浏览的图像以保存为指定的文件。 
  
  
(a) 浏览图像时的界面 
  
 
  
(b) 另存图像时的界面 
图1 PNG图像浏览器 
五、结语 
PNG是一种常见的图像文件格式,本文设计了一个用于读写PNG图像的类,类中除函数Draw() 使用了MFC中的CDC类指针外,其余的成员函数设计均采用标准C和C++语言;因此只需将显示函数Draw()作适当修改或者直接删除,即可将这个类应用到其他的C++开发平台,如C++ Builder,具有较好的移植性。文中的PNG图像浏览器是在VC++6.0平台上设计,其设计步骤和具体代码均适用于VC++.NET 2003和 VC++.NET 2005平台。 
  
参考文献 
  
[1]http://www.libpng.org/pub/png/#history. 
[2]http://www.libpng.org/pub/png/spec/iso/index-object.html. 
[3]http://www.libpng.org/pub/png/libpng.html. 
[4]http://www.zlib.net/. 			
				 |