C# Winform 显示Gif动图

转载于
http://www.cnblogs.com/cpw999cn/archive/2009/02/07/1385885.html

原文标题是:C# Winform中绘制动画的方法
以下是原文。


最近在做一个图片查看器,由于使用一般的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;   
                    frameDimension = new FrameDimension(guid[0]);   
                    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();   
        }   
    }   
}

有点不完美的地方,在Paint事件中,必须锁定Image,否则很容易出现“对象当前正在其他地方使用。”的异常,因为AnimateImage也在使用这个Image对象。如果你有更好的解决办法,欢迎给我留言~~

### 回答1: 在 Winform 中播放 GIF 可以通过使用 PictureBox 控件来实现。以下是实现的步骤: 1. 首先,在 Visual Studio 的 Winform 项目中添加一个 PictureBox 控件。可以通过拖拽方式从工具箱中添加。 2. 在代码中,指定 GIF 文件的路径。可以在项目的资源文件夹中添加 GIF 文件,并通过路径访问。 3. 使用 Image 对象加载 GIF 文件,并将其赋值给 PictureBox 控件的 Image 属性。 示例代码如下: ```c# // 指定 GIF 文件的路径 string gifPath = "路径/至/您的/GIF/文件.gif"; // 使用 Image 对象加载 GIF 文件 Image gifImage = Image.FromFile(gifPath); // 将 Image 对象赋值给 PictureBox 控件的 Image 属性 pictureBox1.Image = gifImage; // 设置 PictureBox 控件的 SizeMode 属性为 AutoSize,让控件自适应图像的大小 pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize; // 设置 PictureBox 控件的 Visible 属性为 true,使其可见 pictureBox1.Visible = true; // 播放 GIF pictureBox1.Image = gifImage; ``` 通过以上步骤,即可在 Winform 中播放 GIF 图片。运行程序时,PictureBox 控件会根据 GIF 图片的帧数自动播放动画。 ### 回答2: Winform是一个用于开发Windows桌面应用程序的框架,它提供了丰富的控件和功能,可以轻松创建各种功能丰富的用户界面。 要在Winform中播放GIF,有几种方法可以实现。以下是其中的一种常见方法: 首先,需要在Winform中添加一个PictureBox控件,并将其大小设置为适当的大小以容纳所需的GIF图像。 然后,在代码中,我们需要使用.NET Framework提供的System.Drawing命名空间的Image对象来加载GIF图像。可以使用Image类的FromStream方法来加载GIF图像的文件流。 接下来,我们需要将加载的GIF图像分解成一系列的帧,然后将每一帧按照指定的时间间隔依次显示在PictureBox控件上。可以使用Image类的SelectActiveFrame方法来选择GIF图像的每一帧。 最后,在Winform的事件处理程序中,可以使用Timer控件来控制每一帧的显示时间,以实现动画的效果。可以在Timer的Tick事件中使用PictureBox控件的Image属性来实现不同帧之间的切换。 总的来说,要在Winform中播放GIF,需要加载GIF图像、分解帧、控制显示时间等步骤。通过使用PictureBox控件和Timer控件,结合Image对象的相关方法,可以实现在Winform应用程序中播放GIF图像的效果。 ### 回答3: 在WinForms应用程序中播放GIF动画相对简单,可以通过PictureBox控件完成。下面是一个示例的步骤: 1. 首先,在设计窗体时将一个PictureBox控件拖放到窗体上,用于显示GIF动画。 2. 确保已经将GIF文件添加到项目中,并设置其"Build Action"属性为"Embedded Resource"。 3. 在窗体的构造函数或Load事件中添加以下代码: ```csharp private void Form1_Load(object sender, EventArgs e) { // 读取嵌入式资源 Assembly assembly = Assembly.GetExecutingAssembly(); Stream stream = assembly.GetManifestResourceStream("YourNamespace.YourGif.gif"); // 创建GIF动画对象 Image gif = Image.FromStream(stream); // 将GIF动画设置为PictureBox的图像 pictureBox1.Image = gif; // 开始播放GIF动画 ImageAnimator.Animate(gif, OnFrameChanged); } // 处理帧改变事件 private void OnFrameChanged(Object sender, EventArgs e) { pictureBox1.Refresh(); // 刷新PictureBox控件以显示下一帧 } ``` 注意要把 "YourNamespace.YourGif.gif" 替换为你项目中的GIF文件的完整资源路径。 通过这些步骤,你的WinForms应用程序就可以播放GIF动画了。这段代码首先读取嵌入式资源中的GIF文件并创建动画对象,然后将其设置为PictureBox的图像,并用ImageAnimator.Animate()方法开始播放动画。帧改变事件OnFrameChanged()将触发PictureBox的Refresh()方法,从而实现动画的播放。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值