.C#窗体上怎么显示动态图片如gif



方法一(简单):用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> On FrameChanged;      
  
     /** <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 (On FrameChanged != null)      
           {      
               On FrameChanged(image, e);      
           }      
       }      
   }      
   

使用如下方法调用:

view plaincopy to clipboardprint?


using System;      
using System.Collections.Generic;      
using System.ComponentModel;      
using System.Da ta;      
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.On FrameChanged += new EventHandler<EventArgs>(image_On FrameChanged);      
             SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);      
         }      
     
        void image_On FrameChanged(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();      
         }      
     }      
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值