您的位置:首页 > 其它

WINCE 如何显示PNG和GIF图片

2010-08-27 16:29 429 查看
以前解决过这个问题的 竟然忘记了 又在网上 找了一天

现在备份起来 ……

wince的开发过程中,经常要涉及到GUI等开发,其强大的功能依赖于微软各种动态库和组件的支持,特别我最近在做仿IPHONE效果的UI时,有很多花稍的图片,只能用PNG格式的图片来实现,这里主要介绍wince下各种图片的显示方法,开发环境是VS2005+wince5.0,源程序为实现PNG和GIF的解码和显示函数。
在一些多媒体项目中,图片显示是必不可少的,然而EVC的标准win32函数中,用于图片操作的只有LoadBitmap和BitBlt等位图函数,当然,用位图示是速度最快的一种方式,但是由于位图的不压缩性,使图片的体积非常大,使有些项目的开发板中,位图占用了大量的磁盘空间,如果使用JPG,GIF等高压缩比的图片,可以大大缩小程序的体积,然而EVC没有直接支持这些图片操作的函数,我们可以使用微软提供的组件去实现这个功能。
首先,在EVC的项目中导入图片资源,导入的类名可使用图片的压缩格式,比方说,要导入JPG?片,可定类名为"JPG",如果是GIF,就是"GIF",这样,在编译内核的时候,图片作为资源可直接在内核中使用,然后开始写代码:
//***************************************************************************************
//函数: LoaResourceImage
//目的: 解码并显示PNG图片
//参数说明:hwnd:传入句柄,lpName:资源文件名,lpType:资源文件类名(unicode),
// i:保留,后面参数为RECT
//***************************************************************************************
void LoaResourceImage(HWND hwnd,LPCWSTR lpName,LPCWSTR lpType,int i,
int left,int right,int bottom,int top)
{
HDC hdc;
HRSRC hr;
DWORD dwsize;
HGLOBAL hg;
LPSTR lp;
HMODULE hModule_Current = GetModuleHandle(NULL);
hr = FindResource(hModule_Current,lpName,lpType);
dwsize = SizeofResource(GetModuleHandle(NULL),hr);
hg = LoadResource(GetModuleHandle(NULL),hr);
lp = (LPSTR)LockResource(hg);
hdc = GetDC(hwnd);
RECT rect;
rect.bottom = bottom;
rect.top = top;
rect.right = right;
rect.left = left;
DrawImage(hdc,lp,dwsize,&rect);
DeleteObject(hr);
}
LoadResourceImage函数主要将图片导入内存,使用这个函数,只要将图片的ID,图片的类名,以及要显示图片的坐标位置输入即可,下面主要是显示的函数代码:
//******************************************************************************
//函数: DrawImage
//目的: 显示PNG图片
//参数说明:hdc:HDC,buffer:数据流BUFFER,size:资源大小,
// rect:RECT
//******************************************************************************
void DrawImage(HDC hdc,const void *buffer,UINT size,LPCRECT rect)
{
IImagingFactory *pImageFactory = NULL;
IImage *pImage = NULL;
CoInitializeEx(NULL,COINIT_MULTITHREADED);
if(SUCCEEDED(CoCreateInstance(CLSID_ImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_IImagingFactory,
(void **)&pImageFactory)))
{

if(SUCCEEDED(pImageFactory->CreateImageFromBuffer(buffer,size,DISPOSAL_NONE,&pImage)))
{
pImage->Draw(hdc,rect,NULL);
pImage->Release();
}
pImageFactory->Release();
}
CoUninitialize();
}
这里使用了微软的组件的调用,然后在指定位置显示,当然,只要组件中支持相应的图片解码,这种方法就可以使用,目前,大多数的解码,wince5.0都可以解,这样wince下的图片显示问题解决。

还有问题就是:

1.头文件的包含次序.
#include "initguid.h"一定要在#include "imaging.h"之前.如果不包含"initguid.h"或在#include "imaging.h"之后含,则编译时会出现错误:
TempApp.obj : error LNK2001: unresolved external symbol CLSID_ImagingFactory
TempApp.obj : error LNK2001: unresolved external symbol IID_IImagingFactory

2."Ole32.lib"需要pragma
如果"Ole32.lib"没有pragma的话,那么编译的时候将会出现如下错误:
TempApp.obj : error LNK2019: unresolved external symbol __imp_CoUninitialize referenced in function "void __cdecl Open(void)" (?Open@@YAXXZ)
TempApp.obj : error LNK2019: unresolved external symbol __imp_CoCreateInstance referenced in function "void __cdecl Open(void)" (?Open@@YAXXZ)
TempApp.obj : error LNK2019: unresolved external symbol __imp_CoInitializeEx referenced in function "void __cdecl Open(void)" (?Open@@YAXXZ)
MIPSIIDbg/TempApp.exe : fatal error LNK1120: 3 unresolved externals

如果将IImage组件用类的形式封装,那么在头文件的包含顺序就更有讲究.

如果将IImage组件用类的形式封装,那么在头文件的包含顺序就更有讲究.

这个是一个完整的能通过编译的例子:

//////////////////////////////////////////////////////////////////////
// TempApp.cpp : Defines the entry point for the application.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "imgtest.h"

int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.

CImgTest imgTest;
imgTest.Open();
return 0;
}
//////////////////////////////////////////////////////////////////////
// ImgTest.h: interface for the CImgTest class.
//
//////////////////////////////////////////////////////////////////////

#ifndef IMGTEST_H
#define IMGTEST_H

#include "imaging.h"

class CImgTest
{
public:
void Open();
CImgTest();
virtual ~CImgTest();

protected:
IImage * pImage;
IImagingFactory * pImagingFactory;
};

#endif //#ifndef IMGTEST_H

//////////////////////////////////////////////////////////////////////
// ImgTest.cpp: implementation of the CImgTest class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "initguid.h"
#include "ImgTest.h"

#pragma comment (lib,"Ole32.lib")

CImgTest::CImgTest()
{

}

CImgTest::~CImgTest()
{

}

void CImgTest::Open()
{

HRESULT hr;

if (FAILED(hr = CoInitializeEx(NULL, COINIT_MULTITHREADED)))
{
goto END;
}

if(FAILED(hr = CoCreateInstance(CLSID_ImagingFactory,NULL,CLSCTX_INPROC_SERVER,IID_IImagingFactory,(void**) &pImagingFactory)))
{
goto END;
}

if(FAILED(hr = pImagingFactory->CreateImageFromFile(TEXT("测试.bmp"), &pImage)))
{
goto END;
}

END:
if(pImage != NULL)
{
pImage->Release();
pImage = NULL;
}

if(pImagingFactory != NULL)
{
pImagingFactory->Release();
pImagingFactory = NULL;
}

CoUninitialize();
}

CImgTest是将IImage COM封装的一个类,在这里例子里我们尤为要注意的是#include "initguid.h"的位置:位于"ImgTest.cpp"中,并且在"ImgTest.h"之前.看到这里,可能有的朋友会觉得奇怪,直接将#include "initguid.h"写在"ImgTest.h"中不行么?答案是否定的.

我们可以更改头文件的包含,做个测试.

更改后的头文件如下:

//////////////////////////////////////////////////////////////////////
// ImgTest.h: interface for the CImgTest class.
//
//////////////////////////////////////////////////////////////////////

#ifndef IMGTEST_H
#define IMGTEST_H

#include "ImgTest.h"
#include "imaging.h"

class CImgTest
{
public:
void Open();
CImgTest();
virtual ~CImgTest();

protected:
IImage * pImage;
IImagingFactory * pImagingFactory;
};

#endif //#ifndef IMGTEST_H

编译时将出现错误:
ImgTest.obj : error LNK2005: ENCODER_SAVE_FLAG already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ENCODER_CHROMINANCE_TABLE already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ENCODER_LUMINANCE_TABLE already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ENCODER_TRANSFORMATION already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ENCODER_ROTATION already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ENCODER_QUALITY already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ENCODER_RENDERMETHOD already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ENCODER_VERSION already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ENCODER_SCANMETHOD already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ENCODER_COLORDEPTH already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ENCODER_COMPRESSION already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: DECODER_USEICC already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: DECODER_ICONRES already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: DECODER_OUTPUTCHANNEL already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: DECODER_TRANSRANGE already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: DECODER_TRANSCOLOR already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: FMTID_JpegAppHeaders already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: FMTID_ImageInformation already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: FRAMEDIM_PAGE already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: FRAMEDIM_RESOLUTION already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: FRAMEDIM_TIME already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IID_IImageBytes already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IID_IBasicBitmapOps already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IID_IImageSink already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IID_IImageEncoder already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IID_IImageDecoder already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IID_IBitmapImage already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IID_IImage already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: CLSID_ImagingFactory already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IID_IImagingFactory already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IMGFMT_ICO already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IMGFMT_FLASHPIX already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IMGFMT_PHOTOCD already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IMGFMT_EXIF already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IMGFMT_TIFF already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IMGFMT_GIF already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IMGFMT_PNG already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IMGFMT_JPEG already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IMGFMT_WMF already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IMGFMT_EMF already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IMGFMT_BMP already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IMGFMT_MEMORYBMP already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: IMGFMT_UNDEFINED already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: CodecIImageBytes already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: EncoderSaveFlag already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: EncoderChrominanceTable already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: EncoderLuminanceTable already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: EncoderTransformation already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: EncoderQuality already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: EncoderRenderMethod already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: EncoderVersion already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: EncoderScanMethod already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: EncoderColorDepth already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: EncoderCompression already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: FormatIDJpegAppHeaders already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: FormatIDImageInformation already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: FrameDimensionPage already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: FrameDimensionResolution already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: FrameDimensionTime already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ImageFormatIcon already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ImageFormatEXIF already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ImageFormatTIFF already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ImageFormatGIF already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ImageFormatPNG already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ImageFormatJPEG already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ImageFormatWMF already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ImageFormatEMF already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ImageFormatBMP already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ImageFormatMemoryBMP already defined in ImageIntroduce.obj
ImgTest.obj : error LNK2005: ImageFormatUndefined already defined in ImageIntroduce.obj

那么在"ImgTest.cpp"中将#include "initguid.h"放置 #include "ImgTest.h"之后也不行么?答案依然是否定的.如果放在之后,则编译时会出现如下错误:
ImgTest.obj : error LNK2001: unresolved external symbol CLSID_ImagingFactory
ImgTest.obj : error LNK2001: unresolved external symbol IID_IImagingFactory
MIPSIIDbg/ImageIntroduce.exe : fatal error LNK1120: 2 unresolved externals

IImage的使用很简单也很方便,唯一需要注意的仅仅是#include "initguid.h"语句的位置而已,而这点却又往往让我们忽略,从而造就一些莫名其妙的链接错误.

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/faintbook/archive/2009/03/24/4019963.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: