C# Winform中繪制動畫的方法


這里介紹一個.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();   
        }   
    }   
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM