原文来自:http://blog.csdn.net/wyfde123/article/details/6034592
方法一(简单):用label,然后设置为背景图片
方法二:使用GDI+ 来实现 (很粗略的实现,没有帧间隔)
方法三:(推荐)
方法四: 使用.NET 自带的类:System.Drawing.ImageAnimator
例子:摘自(http://www.cnblogs.com/cpw999cn/archive/2009/02/07/1385885.html)
最近在做一个图片查看器,由于使用一般的PctureBox,在性能和缩放控制上都无法满足预期的要求,因此所有组件的呈现均是通过重写控件的OnPaint事件来绘制。在查看gif图片时发现Graphics.DrawImage只呈现第一帧,无法满足预期要求,因此经过摸索寻找到了解决自绘gif的较好办法。
这里介绍一个.net自身携带的类ImageAnimator,这个类类似于控制动画的时间轴,使用ImageAnimator.CanAnimate可以判断一个图片是否为动画,调用ImageAnimator.Animate可以开始播放动画,即每经过一帧的时间触发一次OnFrameChanged委托,我们只要在该委托中将Image的活动帧选至下一帧再迫使界面重绘就可以实现动画效果了。
为了方便以后的使用,我将这些代码整合到了一起,形成一个AnimateImage类,该类提供了CanAnimate、FrameCount、CurrentFrame等属性,以及Play()、Stop()、Reset()等动画常用的方法,代码如下
- usingSystem;
- usingSystem.Collections.Generic;
- usingSystem.Text;
- usingSystem.Drawing;
- usingSystem.Drawing.Imaging;
-
- namespaceGifTest
- {
-
/// -
///表示一类带动画功能的图像。 -
/// -
public classAnimateImage -
{ -
Image image; -
FrameDimensionframeDimension; -
/// -
///动画当前帧发生改变时触发。 -
/// -
publicevent EventHandlerOnFrameChanged; -
-
/// -
///实例化一个AnimateImage。 -
/// -
///动画图片。 -
publicAnimateImage(Imageimg) -
{ -
image = img; -
lock(image) -
{ -
mCanAnimate =ImageAnimator.CanAnimate(image); -
if(mCanAnimate) -
{ -
Guid[] guid =image.FrameDimensionsList; -
mFrameCount =image.GetFrameCount(frameDimension); -
} -
} -
} -
-
boolmCanAnimate; -
intmFrameCount = 1, mCurrentFrame =0; -
-
/// -
///图片。 -
/// -
publicImage Image -
{ -
get{ return image;} -
} -
-
/// -
///是否动画。 -
/// -
publicboolCanAnimate -
{ -
get{ return mCanAnimate;} -
} -
-
/// -
///总帧数。 -
/// -
publicintFrameCount -
{ -
get{ return mFrameCount;} -
} -
-
/// -
///播放的当前帧。 -
/// -
publicintCurrentFrame -
{ -
get{ return mCurrentFrame;} -
} -
/// -
///播放这个动画。 -
/// -
publicvoid Play() -
{ -
if(mCanAnimate) -
{ -
lock(image) -
{ -
ImageAnimator.Animate(image, newEventHandler(FrameChanged)); -
} -
} -
} -
-
/// -
///停止播放。 -
/// -
publicvoid Stop() -
{ -
if(mCanAnimate) -
{ -
lock(image) -
{ -
ImageAnimator.StopAnimate(image, newEventHandler(FrameChanged)); -
} -
} -
} -
-
/// -
///重置动画,使之停止在第0帧位置上。 -
/// -
publicvoid Reset() -
{ -
if(mCanAnimate) -
{ -
ImageAnimator.StopAnimate(image, newEventHandler(FrameChanged)); -
lock(image) -
{ -
image.SelectActiveFrame(frameDimension,0); -
mCurrentFrame =0; -
} -
} -
} -
-
privatevoid FrameChanged(object sender, EventArgse) -
{ -
mCurrentFrame = mCurrentFrame + 1 >= mFrameCount ? 0 :mCurrentFrame +1; -
lock(image) -
{ -
image.SelectActiveFrame(frameDimension,mCurrentFrame); -
} -
if(OnFrameChanged !=null) -
{ -
OnFrameChanged(image,e); -
} -
} -
} -
使用如下方法调用:
viewplaincopyto clipboardprint?
- usingSystem;
- usingSystem.Collections.Generic;
- usingSystem.ComponentModel;
- usingSystem.Data;
- usingSystem.Drawing;
- usingSystem.Drawing.Imaging;
- usingSystem.Text;
- usingSystem.Windows.Forms;
-
- namespaceGifTest
- {
-
publicpartial class Form1 :Form -
{ -
AnimateImageimage; -
-
publicForm1() -
{ -
InitializeComponent(); -
image = new AnimateImage(Image.FromFile(@"C:/Documents andSettings/Administrator/My Documents/MyPictures/未命名.gif")); -
image.OnFrameChanged += newEventHandler(image_OnFrameChanged); -
SetStyle(ControlStyles.OptimizedDoubleBuffer |ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint,true); -
} -
-
voidimage_OnFrameChanged(object sender, EventArgse) -
{ -
Invalidate(); -
} -
-
privatevoid Form1_Load(object sender, EventArgse) -
{ -
image.Play(); -
} -
-
privatevoid Form1_Paint(object sender, PaintEventArgse) -
{ -
lock(image.Image) -
{ -
e.Graphics.DrawImage(image.Image, new Point(0,0)); -
} -
} -
-
privatevoid button1_Click(object sender, EventArgse) -
{ -
if(button1.Text.Equals("Stop")) -
{ -
image.Stop(); -
button1.Text ="Play"; -
} -
else -
{ -
image.Play(); -
button1.Text ="Stop"; -
} -
Invalidate(); -
} -
-
privatevoid button2_Click(object sender, EventArgse) -
{ -
image.Reset(); -
button1.Text ="Play"; -
Invalidate(); -
} -
} - }