在Pocket PC上显示PNG、JPG等图片






4.94/5 (14投票s)
将CXImage和DibSectionLite结合在Pocket PC上。
引言
在开发一个PocketPC家庭自动化客户端时,我需要一种在设备上显示用户自定义图片的方法。我在CodeProject上找到了一些非常优秀且有用的代码,并能够将它们(经过一些修改和增强)组合成一组非常有用的库。
我不会深入细节,基本上我采用了Chris Maunder的 DibSectionLite,并添加了使用Davide Pizzolato的 CXImage类加载的方法。你可以在这个网站上找到他们原始的库和文档。这里没有必要重复说明。
详细说明
大部分工作是将原始CXImage库修改为使其在PocketPC上编译(使用eVC 3.0)。这需要一些#define
更改和 #ifdef
排除任何 try...catch
代码。我选择返回 false
。下一步是调试PNG代码。由于PNG库使用函数指针,eVC在调试和发布构建之间会修改签名。除非修改这些函数的签名如下,否则返回时堆栈会损坏。
#if defined (_WIN32_WCE) && !defined (_DEBUG) #define _CDECL_MODE_ __cdecl #else #define _CDECL_MODE_ #endif static void _CDECL_MODE_ user_write_data(png_structp png_ptr, png_bytep data, png_size_t length)最后,我修改了DibSectionLite以包含
- CodeProject上发布的所有建议修复(包括16位、24位图像)。
- 裁剪。我有一个平面图图像需要在屏幕上平移,裁剪在只显示图像的一部分时非常快。
- 原始的
Load
和Save
现在接受一个CFile
或CString
.. 对于内存图像(CMemFile
)很有用。 - 通过
CXImage
加载图像。
你可以根据这些定义以及 CXImage
中的定义来添加支持并缩小/扩展你的可执行文件大小。
#define DIBSECTION_SUPPORT_BMP 1 #define DIBSECTION_SUPPORT_GIF 1 // Patented! #define DIBSECTION_SUPPORT_JPG 1 #define DIBSECTION_SUPPORT_PNG 1 //#define DIBSECTION_SUPPORT_MNG 0 // Orig. Lib disabled this #define DIBSECTION_SUPPORT_ICO 1 //#define DIBSECTION_SUPPORT_TIF 0 // Patented! //too many problems with // __cdecl, see header //jk #define DIBSECTION_SUPPORT_TGA 1 #define DIBSECTION_SUPPORT_PCX 1 //#define DIBSECTION_SUPPORT_WBMP 0 //totally corrupt image... This might // take some work. //jk //#define DIBSECTION_SUPPORT_WMF 0 // WMF and PocketPC don't go hand-in hand // too well (GetEnhMetaFilePaletteEntries // unsupported by the OS). //#define DIBSECTION_SUPPORT_J2K 0 // Beta //totally corrupt image... This //might take some work. //jk #define DIBSECTION_SUPPORT_JBG 1 // Patented! see ../jbig/patents.htm
新的加载方法如下
BOOL LoadPNG(LPCTSTR lpszFileName); BOOL LoadJPG(LPCTSTR lpszFileName); BOOL LoadBMP(LPCTSTR lpszFileName); BOOL LoadGIF(LPCTSTR lpszFileName); BOOL LoadMNG(LPCTSTR lpszFileName); BOOL LoadICO(LPCTSTR lpszFileName); BOOL LoadTIF(LPCTSTR lpszFileName); BOOL LoadTGA(LPCTSTR lpszFileName); BOOL LoadPCX(LPCTSTR lpszFileName); BOOL LoadWBMP(LPCTSTR lpszFileName); BOOL LoadWMF(LPCTSTR lpszFileName); BOOL LoadJ2K(LPCTSTR lpszFileName); BOOL LoadJBG(LPCTSTR lpszFileName);代码解开并构建成一堆 .LIB 文件。
你可以为你的设备编译和构建PocketPCTest应用程序。它没什么花哨的。只是一个测试器。根据需要取消注释PocketPCTestView.cpp中的行。
测试应用程序包含一个
CDIBSectionLite m_image;在头文件中。
用于绘制
void CPocketPCTestView::OnDraw(CDC* pDC) { CPocketPCTestDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here m_image.Draw(pDC, CPoint(0,0)); }以及用于加载
CPocketPCTestView::CPocketPCTestView() { // TODO: add construction code here m_image.LoadPNG(_T("\\test.png")); // 24bit OK // m_image.LoadPNG(_T("\\test-pal.png")); // 256 OK // m_image.LoadJPG(_T("\\test.JPG")); //ok // m_image.LoadBMP(_T("\\test.BMP")); //ok // m_image.LoadGIF(_T("\\test.GIF")); //ok // m_image.LoadICO(_T("\\test.ICO")); //ok // m_image.LoadTGA(_T("\\test.TGA")); //ok // m_image.LoadPCX(_T("\\test.PCX")); //ok // m_image.LoadJBG(_T("\\test.JBG")); //ok // This wasn't in the original code. //// m_image.LoadMNG(_T("\\test.MNG")); // WMF and PocketPC don't go hand-in hand too well (GetEnhMetaFilePaletteEntries // unsupported by the OS). //// m_image.LoadWMF(_T("\\test.WMF")); // too many problems with __cdecl, see header //// m_image.LoadTIF(_T("\\test.TIF")); // totally corrupt image... This might take some work. //// m_image.LoadWBMP(_T("\\test.WBMP")); // totally corrupt image... This might take some work. //// m_image.LoadJ2K(_T("\\test.J2K")); }差不多就是这样了。我没有花太多时间让J2K、TIF和WBMP正常工作。如果有人让它们工作,我会更新这篇文章。
感谢Chris和Davide,以及所有为他们的文章做出贡献的人。我希望这些更改/修复能够回到你们原始的库中,以便我们PocketPC开发者可以开箱即用地使用你们的代码。