方法一(簡單):用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();
}
}
}
該文章在 2024/12/14 12:39:21 編輯過