方法一(简单):用label,然后设置为背景图片
方法二:使用GDI+ 来实现 (很粗略的实现,没有帧间隔)
-
Image image = Image.FromFile( "e://temp.gif");
-
-
FrameDimension fd = new FrameDimension(image.FrameDimensionsList[0]);
-
-
int count = image.GetFrameCount(fd);
-
-
Graphics g = this.panel1.CreateGraphics();
-
-
while (true) {
-
for (int i = 0; i < count; i++){
-
//g.Clear(Color.White);
-
image.SelectActiveFrame(fd, i);
-
g.DrawImage(image, new Point(0, 0));
-
System.Threading.Thread.Sleep( 100);
-
Application.DoEvents();
-
}
-
}
方法三:(推荐)
-
Bitmap animatedGif = new Bitmap("e://temp2.gif");
-
Graphics g = this.panel1.CreateGraphics();
-
// A Gif image's frame delays are contained in a byte array
-
// in the image's PropertyTagFrameDelay Property Item's
-
// value property.
-
// Retrieve the byte array...
-
int PropertyTagFrameDelay = 0x5100;
-
PropertyItem propItem = animatedGif.GetPropertyItem(PropertyTagFrameDelay);
-
byte[] bytes = propItem.Value;
-
// Get the frame count for the Gif...
-
FrameDimension frameDimension = new FrameDimension(animatedGif.FrameDimensionsList[0]);
-
int frameCount = animatedGif.GetFrameCount(FrameDimension.Time);
-
// Create an array of integers to contain the delays,
-
// in hundredths of a second, between each frame in the Gif image.
-
int[] delays = new int[frameCount + 1];
-
int i = 0;
-
for (i = 0; i <= frameCount - 1; i++)
-
{
-
delays[i] = BitConverter.ToInt32(bytes, i * 4);
-
}
-
-
// Play the Gif one time...
-
while (true)
-
{
-
for (i = 0; i <= animatedGif.GetFrameCount(frameDimension) - 1; i++)
-
{
-
animatedGif.SelectActiveFrame(frameDimension, i);
-
g.DrawImage(animatedGif, new Point(0, 0));
-
Application.DoEvents();
-
Thread.Sleep(delays[i] * 10);
-
}
-
}
方法四: 使用.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()等动画常用的方法,代码如下
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Drawing;
- using System.Drawing.Imaging;
- namespace GifTest
- {
- /**//// <summary>
- /// 表示一类带动画功能的图像。
- /// </summary>
- public class AnimateImage
- {
- Image image;
- FrameDimension frameDimension;
- /**//// <summary>
- /// 动画当前帧发生改变时触发。
- /// </summary>
- public event EventHandler<EventArgs> OnFrameChanged;
- /**//// <summary>
- /// 实例化一个AnimateImage。
- /// </summary>
- /// <param name="img">动画图片。</param>
- public AnimateImage(Image img)
- {
- image = img;
- lock (image)
- {
- mCanAnimate = ImageAnimator.CanAnimate(image);
- if (mCanAnimate)
- {
- Guid[] guid = image.FrameDimensionsList;
- mFrameCount = image.GetFrameCount(frameDimension);
- }
- }
- }
- bool mCanAnimate;
- int mFrameCount = 1, mCurrentFrame = 0;
- /**//// <summary>
- /// 图片。
- /// </summary>
- public Image Image
- {
- get { return image; }
- }
- /**//// <summary>
- /// 是否动画。
- /// </summary>
- public bool CanAnimate
- {
- get { return mCanAnimate; }
- }
- /**//// <summary>
- /// 总帧数。
- /// </summary>
- public int FrameCount
- {
- get { return mFrameCount; }
- }
- /**//// <summary>
- /// 播放的当前帧。
- /// </summary>
- public int CurrentFrame
- {
- get { return mCurrentFrame; }
- }
- /**//// <summary>
- /// 播放这个动画。
- /// </summary>
- public void Play()
- {
- if (mCanAnimate)
- {
- lock (image)
- {
- ImageAnimator.Animate(image, new EventHandler(FrameChanged));
- }
- }
- }
- /**//// <summary>
- /// 停止播放。
- /// </summary>
- public void Stop()
- {
- if (mCanAnimate)
- {
- lock (image)
- {
- ImageAnimator.StopAnimate(image, new EventHandler(FrameChanged));
- }
- }
- }
- /**//// <summary>
- /// 重置动画,使之停止在第0帧位置上。
- /// </summary>
- public void Reset()
- {
- if (mCanAnimate)
- {
- ImageAnimator.StopAnimate(image, new EventHandler(FrameChanged));
- lock (image)
- {
- image.SelectActiveFrame(frameDimension, 0);
- mCurrentFrame = 0;
- }
- }
- }
- private void FrameChanged(object sender, EventArgs e)
- {
- mCurrentFrame = mCurrentFrame + 1 >= mFrameCount ? 0 : mCurrentFrame + 1;
- lock (image)
- {
- image.SelectActiveFrame(frameDimension, mCurrentFrame);
- }
- if (OnFrameChanged != null)
- {
- OnFrameChanged(image, e);
- }
- }
- }
使用如下方法调用:
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.Text;
- using System.Windows.Forms;
- namespace GifTest
- {
- public partial class Form1 : Form
- {
- AnimateImage image;
- public Form1()
- {
- InitializeComponent();
- image = new AnimateImage(Image.FromFile(@"C:/Documents and Settings/Administrator/My Documents/My Pictures/未命名.gif"));
- image.OnFrameChanged += new EventHandler<EventArgs>(image_OnFrameChanged);
- SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
- }
- void image_OnFrameChanged(object sender, EventArgs e)
- {
- Invalidate();
- }
- private void Form1_Load(object sender, EventArgs e)
- {
- image.Play();
- }
- private void Form1_Paint(object sender, PaintEventArgs e)
- {
- lock (image.Image)
- {
- e.Graphics.DrawImage(image.Image, new Point(0, 0));
- }
- }
- private void button1_Click(object sender, EventArgs e)
- {
- if (button1.Text.Equals("Stop"))
- {
- image.Stop();
- button1.Text = "Play";
- }
- else
- {
- image.Play();
- button1.Text = "Stop";
- }
- Invalidate();
- }
- private void button2_Click(object sender, EventArgs e)
- {
- image.Reset();
- button1.Text = "Play";
- Invalidate();
- }
- }
- }