用GDI+显示GIF动画的一个类
2007-11-06 11:45
453 查看
源码
#pragma once
#include <gdiplus.h>
#pragma comment(lib,"gdiplus.lib")
using namespace Gdiplus;
class GIFImage:public Image
{
public:
GIFImage(LPCTSTR sResourceType,LPCTSTR sResource);
GIFImage(const WCHAR *filename,BOOL useEmbeddedColorManagement=FALSE);
~GIFImage();
void GetSize(SIZE *pSize);
bool IsAnimatedGIF() { return m_nFrameCount>1; }
void SetPause(bool bPause);
bool IsPaused() { return m_bPause; }
bool InitAnimation(HWND hWnd,POINT pt);
void ThreadAnimation();
void Destroy();
protected:
bool TestForAnimatedGIF();
void Initialize();
bool DrawFrameGIF();
bool LoadFromBuffer(BYTE* pBuff, int nSize);
bool GetResource(LPCTSTR lpName,LPCTSTR lpType,void *pResource,int &nBufSize);
bool Load(LPCTSTR sResourceType,LPCTSTR sResource);
IStream *m_pStream;
HANDLE m_hThread;
HANDLE m_hPause;
HANDLE m_hExitEvent;
HINSTANCE m_hInst;
HWND m_hWnd;
UINT m_nFrameCount;
UINT m_nFramePosition;
bool m_bIsInitialized;
bool m_bPause;
PropertyItem *m_pPropertyItem;
POINT m_pt;
};
// GDIPlusHelper.cpp: implementation of the CGDIPlusHelper class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GIFImage.h"
#include <process.h>
GIFImage::GIFImage(LPCTSTR sResourceType,LPCTSTR sResource)
{
Initialize();
if(Load(sResourceType,sResource))
{
nativeImage=NULL;
lastResult=DllExports::GdipLoadImageFromStreamICM(m_pStream,&nativeImage);
TestForAnimatedGIF();
}
}
GIFImage::GIFImage(const WCHAR *filename,BOOL useEmbeddedColorManagement):Image(filename,useEmbeddedColorManagement)
{
Initialize();
m_bIsInitialized=true;
TestForAnimatedGIF();
}
GIFImage::~GIFImage()
{
Destroy();
}
DWORD WINAPI ThreadAnimationProc(LPVOID pParam)
{
GIFImage *pImage=(GIFImage *)(pParam);
pImage->ThreadAnimation();
return 0;
}
bool GIFImage::InitAnimation(HWND hWnd,POINT pt)
{
m_hWnd=hWnd;
m_pt.x=pt.x;
m_pt.y=pt.y;
if(!m_bIsInitialized)
{
return false;
}
if(IsAnimatedGIF())
{
if(m_hThread==NULL)
{
DWORD nTID=0;
m_hThread=CreateThread(NULL,0,ThreadAnimationProc,this,CREATE_SUSPENDED,&nTID);
if(!m_hThread)
{
return true;
}
else ResumeThread(m_hThread);
}
}
return false;
}
bool GIFImage::LoadFromBuffer(BYTE* pBuff,int nSize)
{
bool bResult=false;
HGLOBAL hGlobal=GlobalAlloc(GMEM_MOVEABLE, nSize);
if(hGlobal)
{
void *pData=GlobalLock(hGlobal);
if(pData) memcpy(pData, pBuff, nSize);
GlobalUnlock(hGlobal);
if(CreateStreamOnHGlobal(hGlobal,TRUE,&m_pStream)==S_OK) bResult=true;
}
return bResult;
}
bool GIFImage::GetResource(LPCTSTR lpName, LPCTSTR lpType,void *pResource, int &nBufSize)
{
HRSRC hResInfo;
HANDLE hRes;
LPSTR lpRes=NULL;
int nLen=0;
bool bResult=FALSE;
//搜寻资源
hResInfo=FindResource(m_hInst,lpName,lpType);
if(hResInfo==NULL)
{
DWORD dwErr=GetLastError();
return false;
}
//加载资源
hRes=LoadResource(m_hInst,hResInfo);
if(hRes==NULL) return false;
//锁定资源
lpRes=(char *)LockResource(hRes);
if(lpRes!=NULL)
{
if(pResource==NULL)
{
nBufSize=SizeofResource(m_hInst , hResInfo);
bResult=true;
}
else
{
if(nBufSize>=(int)SizeofResource(m_hInst,hResInfo))
{
memcpy(pResource,lpRes,nBufSize);
bResult=true;
}
}
UnlockResource(hRes);
}
//释放资源
FreeResource(hRes);
return bResult;
}
bool GIFImage::Load(LPCTSTR sResourceType, LPCTSTR sResource)
{
bool bResult=false;
BYTE *pBuff=NULL;
int nSize=0;
if(GetResource(sResource,sResourceType,pBuff,nSize))
{
if(nSize>0)
{
pBuff=new BYTE[nSize];
if(GetResource(sResource,sResourceType,pBuff,nSize))
{
if(LoadFromBuffer(pBuff, nSize))
{
bResult=true;
}
}
delete []pBuff;
}
}
m_bIsInitialized=bResult;
return bResult;
}
void GIFImage::GetSize(SIZE *pSize)
{
pSize->cx=GetWidth();
pSize->cy=GetHeight();
}
bool GIFImage::TestForAnimatedGIF()
{
UINT count=0;
count=GetFrameDimensionsCount();
GUID *pDimensionIDs=new GUID[count];
//得到帧维数列表
GetFrameDimensionsList(pDimensionIDs,count);
//得到第一个帧维数的帧数
m_nFrameCount=GetFrameCount(&pDimensionIDs[0]);
//得到属性项大小
int nSize = GetPropertyItemSize(PropertyTagFrameDelay);
//为属性项分配缓冲区
m_pPropertyItem=(PropertyItem *)malloc(nSize);
GetPropertyItem(PropertyTagFrameDelay,nSize,m_pPropertyItem);
delete pDimensionIDs;
return m_nFrameCount>1;
}
void GIFImage::Initialize()
{
m_pStream=NULL;
m_nFramePosition=0;
m_nFrameCount=0;
m_pStream=NULL;
lastResult=InvalidParameter;
m_hThread=NULL;
m_bIsInitialized=false;
m_pPropertyItem=NULL;
m_hInst=NULL;
m_bPause=false;
m_hExitEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
m_hPause=CreateEvent(NULL,TRUE,TRUE,NULL);
}
void GIFImage::ThreadAnimation()
{
m_nFramePosition=0;
bool bExit=false;
while(bExit==false)
{
bExit=DrawFrameGIF();
}
}
bool GIFImage::DrawFrameGIF()
{
WaitForSingleObject(m_hPause,INFINITE);
GUID pageGuid=FrameDimensionTime;
long hmWidth=GetWidth();
long hmHeight=GetHeight();
HDC hDC=GetDC(m_hWnd);
if(hDC)
{
Graphics graphics(hDC);
graphics.DrawImage(this,m_pt.x,m_pt.y,hmWidth,hmHeight);
ReleaseDC(m_hWnd,hDC);
}
SelectActiveFrame(&pageGuid,m_nFramePosition++);
if(m_nFramePosition==m_nFrameCount) m_nFramePosition=0;
long lPause=((long *)m_pPropertyItem->value)[m_nFramePosition]*10;
DWORD dwErr=WaitForSingleObject(m_hExitEvent, lPause);
return dwErr==WAIT_OBJECT_0;
}
void GIFImage::SetPause(bool bPause)
{
if(!IsAnimatedGIF()) return;
if(bPause&&!m_bPause)
{
ResetEvent(m_hPause);
}
else
{
if(m_bPause&&!bPause)
{
SetEvent(m_hPause);
}
}
m_bPause=bPause;
}
void GIFImage::Destroy()
{
if(m_hThread)
{
SetPause(false);
SetEvent(m_hExitEvent);
WaitForSingleObject(m_hThread,INFINITE);
}
CloseHandle(m_hThread);
CloseHandle(m_hExitEvent);
CloseHandle(m_hPause);
free(m_pPropertyItem);
m_pPropertyItem=NULL;
m_hThread=NULL;
m_hExitEvent=NULL;
m_hPause=NULL;
if(m_pStream) m_pStream->Release();
}
使用方法
在窗口初始化时添加(你要添加先加Gif图片资源咯"GIF","HEARTS")
GIFImage *m_image;
m_image=new GIFImage("GIF","HEARTS" );
CRect rc;
GetClientRect(rc);
int cx=(rc.Width()-m_image->GetWidth())/2;
m_image->InitAnimation(m_hWnd,CPoint(cx,10));
#pragma once
#include <gdiplus.h>
#pragma comment(lib,"gdiplus.lib")
using namespace Gdiplus;
class GIFImage:public Image
{
public:
GIFImage(LPCTSTR sResourceType,LPCTSTR sResource);
GIFImage(const WCHAR *filename,BOOL useEmbeddedColorManagement=FALSE);
~GIFImage();
void GetSize(SIZE *pSize);
bool IsAnimatedGIF() { return m_nFrameCount>1; }
void SetPause(bool bPause);
bool IsPaused() { return m_bPause; }
bool InitAnimation(HWND hWnd,POINT pt);
void ThreadAnimation();
void Destroy();
protected:
bool TestForAnimatedGIF();
void Initialize();
bool DrawFrameGIF();
bool LoadFromBuffer(BYTE* pBuff, int nSize);
bool GetResource(LPCTSTR lpName,LPCTSTR lpType,void *pResource,int &nBufSize);
bool Load(LPCTSTR sResourceType,LPCTSTR sResource);
IStream *m_pStream;
HANDLE m_hThread;
HANDLE m_hPause;
HANDLE m_hExitEvent;
HINSTANCE m_hInst;
HWND m_hWnd;
UINT m_nFrameCount;
UINT m_nFramePosition;
bool m_bIsInitialized;
bool m_bPause;
PropertyItem *m_pPropertyItem;
POINT m_pt;
};
// GDIPlusHelper.cpp: implementation of the CGDIPlusHelper class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GIFImage.h"
#include <process.h>
GIFImage::GIFImage(LPCTSTR sResourceType,LPCTSTR sResource)
{
Initialize();
if(Load(sResourceType,sResource))
{
nativeImage=NULL;
lastResult=DllExports::GdipLoadImageFromStreamICM(m_pStream,&nativeImage);
TestForAnimatedGIF();
}
}
GIFImage::GIFImage(const WCHAR *filename,BOOL useEmbeddedColorManagement):Image(filename,useEmbeddedColorManagement)
{
Initialize();
m_bIsInitialized=true;
TestForAnimatedGIF();
}
GIFImage::~GIFImage()
{
Destroy();
}
DWORD WINAPI ThreadAnimationProc(LPVOID pParam)
{
GIFImage *pImage=(GIFImage *)(pParam);
pImage->ThreadAnimation();
return 0;
}
bool GIFImage::InitAnimation(HWND hWnd,POINT pt)
{
m_hWnd=hWnd;
m_pt.x=pt.x;
m_pt.y=pt.y;
if(!m_bIsInitialized)
{
return false;
}
if(IsAnimatedGIF())
{
if(m_hThread==NULL)
{
DWORD nTID=0;
m_hThread=CreateThread(NULL,0,ThreadAnimationProc,this,CREATE_SUSPENDED,&nTID);
if(!m_hThread)
{
return true;
}
else ResumeThread(m_hThread);
}
}
return false;
}
bool GIFImage::LoadFromBuffer(BYTE* pBuff,int nSize)
{
bool bResult=false;
HGLOBAL hGlobal=GlobalAlloc(GMEM_MOVEABLE, nSize);
if(hGlobal)
{
void *pData=GlobalLock(hGlobal);
if(pData) memcpy(pData, pBuff, nSize);
GlobalUnlock(hGlobal);
if(CreateStreamOnHGlobal(hGlobal,TRUE,&m_pStream)==S_OK) bResult=true;
}
return bResult;
}
bool GIFImage::GetResource(LPCTSTR lpName, LPCTSTR lpType,void *pResource, int &nBufSize)
{
HRSRC hResInfo;
HANDLE hRes;
LPSTR lpRes=NULL;
int nLen=0;
bool bResult=FALSE;
//搜寻资源
hResInfo=FindResource(m_hInst,lpName,lpType);
if(hResInfo==NULL)
{
DWORD dwErr=GetLastError();
return false;
}
//加载资源
hRes=LoadResource(m_hInst,hResInfo);
if(hRes==NULL) return false;
//锁定资源
lpRes=(char *)LockResource(hRes);
if(lpRes!=NULL)
{
if(pResource==NULL)
{
nBufSize=SizeofResource(m_hInst , hResInfo);
bResult=true;
}
else
{
if(nBufSize>=(int)SizeofResource(m_hInst,hResInfo))
{
memcpy(pResource,lpRes,nBufSize);
bResult=true;
}
}
UnlockResource(hRes);
}
//释放资源
FreeResource(hRes);
return bResult;
}
bool GIFImage::Load(LPCTSTR sResourceType, LPCTSTR sResource)
{
bool bResult=false;
BYTE *pBuff=NULL;
int nSize=0;
if(GetResource(sResource,sResourceType,pBuff,nSize))
{
if(nSize>0)
{
pBuff=new BYTE[nSize];
if(GetResource(sResource,sResourceType,pBuff,nSize))
{
if(LoadFromBuffer(pBuff, nSize))
{
bResult=true;
}
}
delete []pBuff;
}
}
m_bIsInitialized=bResult;
return bResult;
}
void GIFImage::GetSize(SIZE *pSize)
{
pSize->cx=GetWidth();
pSize->cy=GetHeight();
}
bool GIFImage::TestForAnimatedGIF()
{
UINT count=0;
count=GetFrameDimensionsCount();
GUID *pDimensionIDs=new GUID[count];
//得到帧维数列表
GetFrameDimensionsList(pDimensionIDs,count);
//得到第一个帧维数的帧数
m_nFrameCount=GetFrameCount(&pDimensionIDs[0]);
//得到属性项大小
int nSize = GetPropertyItemSize(PropertyTagFrameDelay);
//为属性项分配缓冲区
m_pPropertyItem=(PropertyItem *)malloc(nSize);
GetPropertyItem(PropertyTagFrameDelay,nSize,m_pPropertyItem);
delete pDimensionIDs;
return m_nFrameCount>1;
}
void GIFImage::Initialize()
{
m_pStream=NULL;
m_nFramePosition=0;
m_nFrameCount=0;
m_pStream=NULL;
lastResult=InvalidParameter;
m_hThread=NULL;
m_bIsInitialized=false;
m_pPropertyItem=NULL;
m_hInst=NULL;
m_bPause=false;
m_hExitEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
m_hPause=CreateEvent(NULL,TRUE,TRUE,NULL);
}
void GIFImage::ThreadAnimation()
{
m_nFramePosition=0;
bool bExit=false;
while(bExit==false)
{
bExit=DrawFrameGIF();
}
}
bool GIFImage::DrawFrameGIF()
{
WaitForSingleObject(m_hPause,INFINITE);
GUID pageGuid=FrameDimensionTime;
long hmWidth=GetWidth();
long hmHeight=GetHeight();
HDC hDC=GetDC(m_hWnd);
if(hDC)
{
Graphics graphics(hDC);
graphics.DrawImage(this,m_pt.x,m_pt.y,hmWidth,hmHeight);
ReleaseDC(m_hWnd,hDC);
}
SelectActiveFrame(&pageGuid,m_nFramePosition++);
if(m_nFramePosition==m_nFrameCount) m_nFramePosition=0;
long lPause=((long *)m_pPropertyItem->value)[m_nFramePosition]*10;
DWORD dwErr=WaitForSingleObject(m_hExitEvent, lPause);
return dwErr==WAIT_OBJECT_0;
}
void GIFImage::SetPause(bool bPause)
{
if(!IsAnimatedGIF()) return;
if(bPause&&!m_bPause)
{
ResetEvent(m_hPause);
}
else
{
if(m_bPause&&!bPause)
{
SetEvent(m_hPause);
}
}
m_bPause=bPause;
}
void GIFImage::Destroy()
{
if(m_hThread)
{
SetPause(false);
SetEvent(m_hExitEvent);
WaitForSingleObject(m_hThread,INFINITE);
}
CloseHandle(m_hThread);
CloseHandle(m_hExitEvent);
CloseHandle(m_hPause);
free(m_pPropertyItem);
m_pPropertyItem=NULL;
m_hThread=NULL;
m_hExitEvent=NULL;
m_hPause=NULL;
if(m_pStream) m_pStream->Release();
}
使用方法
在窗口初始化时添加(你要添加先加Gif图片资源咯"GIF","HEARTS")
GIFImage *m_image;
m_image=new GIFImage("GIF","HEARTS" );
CRect rc;
GetClientRect(rc);
int cx=(rc.Width()-m_image->GetWidth())/2;
m_image->InitAnimation(m_hWnd,CPoint(cx,10));
相关文章推荐
- 用GDI+显示GIF动画的一个类
- GDI+显示GIF动画
- GDI+显示GIF动画
- 介绍一个Android开源项目:GifView——Android显示GIF动画
- 介绍一个Android开源项目:GifView——Android显示GIF动画
- GDI+显示gif动画ImageEx类
- GDI+显示GIF动画
- PMEdit一个富文本框可以编辑文本、并可以显示GIF动画
- GDI+显示GIF动画
- GDI+显示GIF动画
- GDI+显示GIF动画
- 利用GDI+显示GIF动画
- Android UI开发第十九篇——介绍一个开源的gifview——Android显示GIF动画
- GDI+显示GIF动画
- Android UI开发第十九篇——介绍一个开源的gifview——Android显示GIF动画
- PictureEx 这是一个能让你轻松的用 VC 显示 GIF 动画的类
- 写了一个实用的图像放大缩小程序,但是动画GIF转换后不会显示了,只有第一帧
- 介绍一个Android开源项目:GifView——Android显示GIF动画
- Android UI开发第十九篇——介绍一个开源的gifview——Android显示GIF动画
- 介绍一个开源的gifview——Android显示GIF动画