c# winform 显示动态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()等动画常用的方法,代码如下

 
  1. using System;      
  2. using System.Collections.Generic;      
  3. using System.Text;      
  4. using System.Drawing;      
  5. using System.Drawing.Imaging;      
  6.      
  7. namespace GifTest      
  8. {      
  9.     /** <summary>      
  10.   /// 表示一类带动画功能的图像。      
  11.   /// </summary>      
  12.   public class AnimateImage      
  13.    {      
  14.        Image image;      
  15.        FrameDimension frameDimension;      
  16.       /** <summary>      
  17.       /// 动画当前帧发生改变时触发。      
  18.       /// </summary>      
  19.       public event EventHandler<EventArgs> OnFrameChanged;      
  20.   
  21.      /** <summary>      
  22.       /// 实例化一个AnimateImage。      
  23.       /// </summary>      
  24.       /// <param name="img">动画图片。</param>      
  25.       public AnimateImage(Image img)      
  26.        {      
  27.            image = img;      
  28.           lock (image)      
  29.           {      
  30.                mCanAnimate = ImageAnimator.CanAnimate(image);      
  31.               if (mCanAnimate)      
  32.                {      
  33.                   Guid[] guid = image.FrameDimensionsList;      
  34.                    mFrameCount = image.GetFrameCount(frameDimension);      
  35.                }      
  36.            }      
  37.        }      
  38.   
  39.      bool mCanAnimate;      
  40.      int mFrameCount = 1, mCurrentFrame = 0;      
  41.   
  42.       /** <summary>      
  43.      /// 图片。      
  44.       /// </summary>      
  45.       public Image Image      
  46.        {      
  47.           get { return image; }      
  48.        }      
  49.   
  50.       /** <summary>      
  51.       /// 是否动画。      
  52.      /// </summary>      
  53.       public bool CanAnimate      
  54.        {      
  55.           get { return mCanAnimate; }      
  56.       }      
  57.   
  58.        /** <summary>      
  59.     /// 总帧数。      
  60.       /// </summary>      
  61.       public int FrameCount      
  62.        {      
  63.            get { return mFrameCount; }      
  64.         }      
  65.   
  66.        /** <summary>      
  67.        /// 播放的当前帧。      
  68.        /// </summary>      
  69.        public int CurrentFrame      
  70.         {      
  71.            get { return mCurrentFrame; }      
  72.         }        
  73.        /** <summary>      
  74.       /// 播放这个动画。      
  75.       /// </summary>      
  76.        public void Play()      
  77.        {      
  78.           if (mCanAnimate)      
  79.            {      
  80.               lock (image)      
  81.                {      
  82.                    ImageAnimator.Animate(image, new EventHandler(FrameChanged));      
  83.                }      
  84.            }      
  85.        }      
  86.   
  87.       /** <summary>      
  88.       /// 停止播放。      
  89.       /// </summary>      
  90.       public void Stop()      
  91.        {      
  92.           if (mCanAnimate)      
  93.            {      
  94.               lock (image)      
  95.                {      
  96.                    ImageAnimator.StopAnimate(image, new EventHandler(FrameChanged));      
  97.                }      
  98.            }      
  99.        }      
  100.   
  101.       /** <summary>      
  102.       /// 重置动画,使之停止在第0帧位置上。      
  103.       /// </summary>      
  104.       public void Reset()      
  105.        {      
  106.           if (mCanAnimate)      
  107.            {      
  108.                ImageAnimator.StopAnimate(image, new EventHandler(FrameChanged));      
  109.               lock (image)      
  110.                {      
  111.                    image.SelectActiveFrame(frameDimension, 0);      
  112.                    mCurrentFrame = 0;      
  113.                }      
  114.            }      
  115.        }      
  116.   
  117.       private void FrameChanged(object sender, EventArgs e)      
  118.        {      
  119.            mCurrentFrame = mCurrentFrame + 1 >= mFrameCount ? 0 : mCurrentFrame + 1;      
  120.           lock (image)      
  121.            {      
  122.                image.SelectActiveFrame(frameDimension, mCurrentFrame);      
  123.            }      
  124.           if (OnFrameChanged != null)      
  125.            {      
  126.                OnFrameChanged(image, e);      
  127.            }      
  128.        }      
  129.    }      

 

使用如下方法调用:

  1. using System;      
  2. using System.Collections.Generic;      
  3. using System.ComponentModel;      
  4. using System.Data;      
  5. using System.Drawing;      
  6. using System.Drawing.Imaging;      
  7. using System.Text;      
  8. using System.Windows.Forms;      
  9.      
  10. namespace GifTest      
  11. {      
  12.     public partial class Form1 : Form      
  13.      {      
  14.          AnimateImage image;      
  15.      
  16.         public Form1()      
  17.          {      
  18.              InitializeComponent();      
  19.              image = new AnimateImage(Image.FromFile(@"C:/Documents and Settings/Administrator/My Documents/My Pictures/未命名.gif"));      
  20.              image.OnFrameChanged += new EventHandler<EventArgs>(image_OnFrameChanged);      
  21.              SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);      
  22.          }      
  23.      
  24.         void image_OnFrameChanged(object sender, EventArgs e)      
  25.          {      
  26.              Invalidate();      
  27.          }      
  28.      
  29.         private void Form1_Load(object sender, EventArgs e)      
  30.          {      
  31.              image.Play();      
  32.          }      
  33.      
  34.         private void Form1_Paint(object sender, PaintEventArgs e)      
  35.          {      
  36.             lock (image.Image)      
  37.              {      
  38.                  e.Graphics.DrawImage(image.Image, new Point(0, 0));      
  39.              }      
  40.          }      
  41.      
  42.         private void button1_Click(object sender, EventArgs e)      
  43.          {      
  44.             if (button1.Text.Equals("Stop"))      
  45.              {      
  46.                  image.Stop();      
  47.                  button1.Text = "Play";      
  48.              }      
  49.             else     
  50.              {      
  51.                  image.Play();      
  52.                  button1.Text = "Stop";      
  53.              }      
  54.              Invalidate();      
  55.          }      
  56.      
  57.         private void button2_Click(object sender, EventArgs e)      
  58.          {      
  59.              image.Reset();      
  60.              button1.Text = "Play";      
  61.              Invalidate();      
  62.          }      
  63.      }      

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值