您的位置:首页 > 其它

如何用IImage组件来播放GIF动画,jpg,png

2010-01-28 15:46 423 查看
如何用IImage组件来播放GIF动画

GIF, IImage, 动画, 组件, 播放转自http://www.devdiv.net/bbs/viewthread.php?tid=9334

如何用IImage组件来播放GIF动画

最近小弟在网上收集资料发现IImage这个com组件相当的强大,有好多地方需要学习和分析的

哎~路还很长...

下面是播放gif动画的过程

IStream* CreateStreamByFileName(LPCTSTR strFileName)
{
HANDLE hFile = CreateFile(strFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return 0;
}

DWORD dwFileSize = GetFileSize(hFile, NULL);

if (dwFileSize == (DWORD)-1)
{
CloseHandle(hFile);
return 0;
}

HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
if (hGlobal == NULL)
{
CloseHandle(hFile);
return 0;
}
LPVOID pvData = GlobalLock(hGlobal);
if (pvData == NULL)
{
GlobalUnlock(hGlobal);
CloseHandle(hFile);
return 0;
}
DWORD dwBytesRead = 0;
BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL);
GlobalUnlock(hGlobal);
CloseHandle(hFile);

if (!bRead)
{
return 0;
}

IStream* pStream = 0;
if (FAILED(CreateStreamOnHGlobal(hGlobal, TRUE, &pStream)))
{
return 0;
}

return pStream;
}
___________________________________________________
IImagingFactory *pImgFactory = NULL;
IImage *pImage = NULL;
ImageInfo *info = NULL;
IStream* pStream = CreateStreamByFileName(L"//Windows//OemAnimationstartup.gif");
IImageDecoder* pDecoder = NULL;
UINT count = 0;
UINT size = 0;
ImageInfo ii = {0};
PropertyItem pi = {0};
GUID guid;
UINT i = 0;
IBitmapImage *bmpimg = NULL;
IImageSink *sink = NULL;
LARGE_INTEGER dlibMove = { 0, 0 };
IBasicBitmapOps *oper = NULL;

hdc = BeginPaint(hwnd, &ps);

if (SUCCEEDED(CoCreateInstance (CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void **)&pImgFactory)))
{

if (SUCCEEDED(pImgFactory->CreateImageDecoder(pStream, DecoderInitFlagNone, &pDecoder)))
{

pDecoder->TerminateDecoder();

pStream->Seek( dlibMove, STREAM_SEEK_SET, NULL );
pDecoder->InitDecoder(pStream, DecoderInitFlagBuiltIn1st);

pDecoder->GetPropertyItemSize(PropertyTagFrameDelay, &size);
pDecoder->GetPropertyItem(PropertyTagFrameDelay, size, &pi);

pDecoder->GetImageInfo(&ii);
pDecoder->GetFrameDimensionsCount(&count);
pDecoder->GetFrameDimensionsList(&guid, count);
pDecoder->GetFrameCount(&guid, &count);

while(i < count)
{
pDecoder->SelectActiveFrame(&guid,i);
pImgFactory->CreateNewBitmap(ii.Width, ii.Height, PixelFormatDontCare, &bmpimg);
bmpimg->QueryInterface(IID_IImageSink, (void**)&sink);
HRESULT hr = pDecoder->BeginDecode(sink, NULL);
pDecoder->Decode();

bmpimg->QueryInterface(IID_IBasicBitmapOps, (void **) &oper);

oper->Rotate(180.0, InterpolationHintDefault, &bmpimg);//这个是将图像翻转,测试用的,不需要可以去掉

bmpimg->QueryInterface(IID_IImage, (void**)&pImage);
pImage->Draw(hdc, &winRect, NULL);
//Sleep(((long*)pi.value)[i]*10);
Sleep((10);
pDecoder->EndDecode(hr);
++i;
}
}
}

pImgFactory->Release();
pImage->Release();
pDecoder->Release();
bmpimg->Release();
sink->Release();
oper->Release();

论坛相关主题

在.net cf环境下,IImage对象创建后怎么样释放?

IImage图片绘制的失真

如何用IImage组件来播放GIF动画

不只是可以显示png,jpg,bmp等等都可以,gif也行,不过只能显示单帧。

一种方法是用IImagingFactory 中的CreateImageFromFile

先看看msdn:

This method lets an application create a decoded image object from a file.

Syntax

HRESULT CreateImageFromFile(
const WCHAR* filename,
IImage** image
);

Parameters
filename
[in] A WCHAR array containing the name of the source file.

image
[out] A pointer to the resulting IImage interface pointer.

Return Value
If successful, this method returns S_OK.

This method may return E_POINTER if it fails.

Remarks
When the decoded image object is created, it only keeps a reference to the external data source and does not immediately decode the image. The decoded image opens the file in read-only mode and allows shared-read access to it.

Be aware that decoded image objects are read-only. In particular, you cannot modify the image data. However, you can display it onto a destination graphics context or push its data into an image sink. For more information, see IImage.

Requirements
OS Versions: Windows CE 5.0 and later.

Header: Imaging.h.

Link Library: Imaging.

所以很简单了

/************************************************************************************
*
* 函数名称 ShowPng
* 函数介绍 显示png图片
* 入口参数 const WCHAR *filename, //文件路径
* CRect *pRect, //显示区域
* CDC *pDc, //dc
* 出口参数 无
* 返回 值 void
*
***********************************************************************************/
void ShowPng(const WCHAR *filename, CRect *pRect, CDC *pDc)
{
IImagingFactory *pImageFactory = NULL;
IImage *pImage = NULL;
HRESULT hrCreInstance = CoCreateInstance( CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER,IID_IImagingFactory, (void **)&pImageFactory);
HRESULT hrLoadFile = pImageFactory->CreateImageFromFile(filename, &pImage);
if (S_OK != hrCreInstance || S_OK != hrLoadFile)
{
AfxMessageBox(L"加载图片失败!!!");
return;
}
pImage->Draw( pDc->GetSafeHdc(), pRect, NULL );

pImage->Release();
pImageFactory->Release();
}
注意:

#include <Imaging.h>

还有另外一种方法:

就是用SHLoadImageFile函数。

先看msdn:

This function reads an image file, decompresses it, and returns a handle to a bitmap in memory.

Syntax

HBITMAP SHLoadImageFile (
LPCTSTR pszFileName
);

Parameters
pszFileName
[in] The name of the image file to be loaded.

Return Value
A handle to a bitmap if successful, NULL otherwise.

Remarks
This function converts files of several types, including GIF (Graphics Interchange Format), PNG (Portable Network Graphics), JPG (Joint Photographic Experts Group), ICO (icon), and BMP (bitmap) file formats. Other image file types may be supported if the correct decoder is installed.

When you no longer need the bitmap, call the DeleteObject function to delete it.

Requirements
Pocket PC: Windows Mobile 2003 and later.

OS Versions: Windows CE .NET 4.0 and later.

Header: Declared in Aygshell.h.

Library: Use Aygshell.lib.

/************************************************************************************
*
* 函数名称 ShowPic
* 函数介绍 显示png图片
* 入口参数 const WCHAR *filename, //文件路径
* CRect *pRect, //显示区域
* CDC *pDc, //dc
* 出口参数 无
* 返回 值 void
*
***********************************************************************************/
void ShowPic(const WCHAR *filename, CRect *pRect, CDC *pDc)
{
CDC dccom;
dccom.CreateCompatibleDC(pDc);
HBITMAP hbitmap = SHLoadImageFile(filename);
CBitmap *bk,pp;
bk = pp.FromHandle(hbitmap);

BITMAP bitmap;
bk->GetBitmap(&bitmap);
CBitmap *pOldbmp = dccom.SelectObject(bk);
pDc->StretchBlt(0,0,pRect->Width(),pRect->Height(),&dccom,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);
}

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/sc_valentine21/archive/2008/12/30/3645709.aspx

Windows Mobile获取系统图片 收藏

通过SHGetFileInfo函数即可获得系统的图片。

WINSHELLAPI DWORD WINAPI SHGetFileInfo(
  LPCTSTR pszPath, 
  DWORD dwFileAttributes, 
  SHFILEINFO FAR* psfi, 
  UINT cbFileInfo, 
  UINT uFlags
);

其实MSDN上有详细的介绍,还有例子。

这里我只是给出我的例子:

CImageList m_ImageList;

HIMAGELIST hImlSys;
SHFILEINFO    ssfi;

memset(&ssfi,0,sizeof(ssfi));
hImlSys = (HIMAGELIST)SHGetFileInfo(
L"//",
0,
&ssfi,
sizeof(SHFILEINFO),
SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_ICON);
m_ImageList.Attach(hImlSys);

这里就将系统的所有图片加载到m_ImageList中了,因为有了SHGFI_USEFILEATTRIBUTES ,所以第一个参数

会被忽略。

但是我想获得某个指定的图片,怎办呢?还是这个函数:

CString strFilePath;//假设这个是某个文件或文件夹的路径,例如_T"//Program Files//Liam.exe"

SHFILEINFO    ssfi;
memset(&ssfi,0,sizeof(ssfi));
SHGetFileInfo(
strFilePath,
0,
&ssfi,
sizeof(SHFILEINFO),
/*SHGFI_USEFILEATTRIBUTES | */SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_ICON);

ssfi.iIcon返回的是一个整数值,返回的是这个图片在刚才加入的图片列表中的索引位置,那么在InsertItem的时候就

可以将其设置并显示了。

尤其需要注意的是,一定记得m_ImageList.Detach();

否则系统的图片都将不可见!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: