在MFC/WTL中如何绘制Gif动态图片
2012-10-16 15:30
381 查看
说明:本文内容参考了 codeproject 的此文,http://www.codeproject.com/Articles/1776/Adding-GIF-animation-using-GDI 。
本文所写代码针对多帧gif,如果是单帧gif,则会出错(可以把Load中的IsAnimate函数放到Start开头判断,如果是单帧,就返回,否则,启动定时器)。代码中有判断的函数。
思路:首先获取帧数,然后每间隔一段时间就绘制一帧。可通过两种方式实现动态,一种是线程,参考上文,另一种是Timer定时器,参考本文。
注:本人不是高手,代码质量不必考究。欢迎改装(因为此代码运行于WTL环境中,改成对应的MFC代码即可)此代码到工程中。
OK,废话别说了,代码开始:
使用方法:
GifWnd gif;
gif.Load("res/star.gif"); //注意,路径不得有误,否则Image::FromFile返回为NULL,接下来自然就会出错。
gif.Create(m_hWnd,CPoint(20,20));
gif.Start();
以下为测试用图,欢迎copy test 。
本文所写代码针对多帧gif,如果是单帧gif,则会出错(可以把Load中的IsAnimate函数放到Start开头判断,如果是单帧,就返回,否则,启动定时器)。代码中有判断的函数。
思路:首先获取帧数,然后每间隔一段时间就绘制一帧。可通过两种方式实现动态,一种是线程,参考上文,另一种是Timer定时器,参考本文。
注:本人不是高手,代码质量不必考究。欢迎改装(因为此代码运行于WTL环境中,改成对应的MFC代码即可)此代码到工程中。
OK,废话别说了,代码开始:
#include <gdiplus.h> using namespace Gdiplus; #pragma comment(lib, "gdiplus.lib") //gdi+相关文件 和 库 // Gif控件 typedef CWinTraits<WS_VISIBLE | WS_CHILD,0> GifTraits; //控制窗口样式 class GifWnd : public CWindowImpl<GifWnd,CStatic,GifTraits> //(此处继承CStatic就可以拖动窗口(当窗口响应了NCHITTEST消息的时候)了) { public: GifWnd() //初始化gdi+ 这种对gdi+环境的初始化和释放在整个程序做一次就行了。因此,可考虑封装到一个类中,此处是为了简便。 { GdiplusStartupInput in; GdiplusStartup(&token,&in,NULL); } ~GifWnd() //释放gdi+ { GdiplusShutdown(token); } void Load(const wchar_t* path) //Image的参数要求的是unicode { img = Image::FromFile(path); width = img->GetWidth(); height = img->GetHeight(); frame_pos = 0; IsAnimate(); } void Create(HWND hWnd,CPoint pt) { __super::Create(hWnd); SetWindowPos(hWnd,pt.x,pt.y,width,height,SWP_NOZORDER); } void Start() //在Start之前,OnPaint已经绘制了第0帧 { long pause = ((long *) pro_item->value)[frame_pos]; //获取第0帧的间隔时间 pause = pause <= 5 ? 100 : pause * 10; //这个是为了让gif显示速度适中,原因参考上面链接中原作者的回答 SetTimer(1212,pause,NULL); } public: BEGIN_MSG_MAP(GifWnd) MSG_WM_TIMER(OnTimer) MSG_WM_PAINT(OnPaint) END_MSG_MAP() public: void OnTimer(UINT_PTR) { GUID guid = FrameDimensionTime; frame_pos++; if(frame_pos >= frame_count) frame_pos = 0; img->SelectActiveFrame(&guid,frame_pos); //指针移到下一帧 Invalidate(); KillTimer(1212); long pause = ((long *) pro_item->value)[frame_pos]; pause = pause <= 5 ? 100 : pause * 10; SetTimer(1212,pause,NULL); //每次间隔时间不一样,我记得CPictureEx类中设置成100了。 } void OnPaint(CDCHandle) { CPaintDC dc(m_hWnd); CMemoryDC mem(dc,CRect(0,0,width,height)); //WTL的双缓存类,析构时自动绘制到dc上。这个是解决闪烁的 Graphics graph(mem); graph.DrawImage(img,0,0,width,height); } private: bool IsAnimate() { UINT cn = img->GetFrameDimensionsCount(); GUID* pGuid = new GUID[cn]; img->GetFrameDimensionsList(pGuid,cn); frame_count = img->GetFrameCount(&pGuid[0]); int sz = img->GetPropertyItemSize(PropertyTagFrameDelay); pro_item = (PropertyItem *) malloc(sz); img->GetPropertyItem(PropertyTagFrameDelay,sz,pro_item); delete pGuid; return frame_count > 1; } private: int width,height; Image *img; int frame_count; int frame_pos; PropertyItem *pro_item; ULONG_PTR token; };
使用方法:
GifWnd gif;
gif.Load("res/star.gif"); //注意,路径不得有误,否则Image::FromFile返回为NULL,接下来自然就会出错。
gif.Create(m_hWnd,CPoint(20,20));
gif.Start();
以下为测试用图,欢迎copy test 。
相关文章推荐
- 如何制作GIF动态图片
- java 如何生成动态的gif图片
- java 如何生成动态的gif图片
- java 如何生成动态的gif图片
- VC的MFC工程加载GIF格式动态图片
- 如何制作动态图片gif
- MFC 加载gif动态图片的方法
- 如何制作gif动态图片
- 如何用photoshop做动态gif图片
- 如何录制gif动态图片并在CSDN中插入动态图片
- MFC加载gif动态图片的方法
- vc6.0中用GDIPlus实现加载动态gif图片(非MFC实现)
- 如何制作gif图片?如何制作你项目的动态效果图到你的csdn?
- 如何将你在FLASH 8.0里制作完成的动态图片保存成GIF格式的文件,我来教你!!!
- 如何制作gif图片?如何制作你项目的动态效果图到你的csdn?
- 如何将你在FLASH 8.0里制作完成的动态图片保存成GIF格式的文件,我来教你!!!
- 如何录制Gif动态图片
- 【ppt入门教程】如何在ppt幻灯片中插入GIF格式动态图片
- 在MFC中用GDI+显示动态GIF图片
- android如何添加gif动态图片