四、实例设计
在设计实例前,先准备好相关的库。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/.
|