C# Winform中繪製動畫的方法

來源:互聯網
上載者:User

 最近在做一個圖片查看器,由於使用一般的PctureBox,在效能和縮放控制上都無法滿足預期的要求,因此所有組件的呈現均是通過重寫控制項的OnPaint事件來繪製。在查看gif圖片時發現Graphics.DrawImage只呈現第一幀,無法滿足預期要求,因此經過摸索尋找到瞭解決自繪gif的較好辦法。

這裡介紹一個.net自身攜帶的類ImageAnimator,這個類類似於控制動畫的時間軸,使用ImageAnimator.CanAnimate可以判斷一個圖片是否為動畫,調用ImageAnimator.Animate可以開始播放動畫,即每經過一幀的時間觸發一次OnFrameChanged委託,我們只要在該委託中將Image的活動幀選至下一幀再迫使介面重繪就可以實現動畫效果了。

為了方便以後的使用,我將這些代碼整合到了一起,形成一個AnimateImage類,該類提供了CanAnimate、FrameCount、CurrentFrame等屬性,以及Play()、Stop()、Reset()等動畫常用的方法,代碼如下

using System;<br /> using System.Collections.Generic;<br /> using System.Text;<br /> using System.Drawing;<br /> using System.Drawing.Imaging; </p><p> namespace GifTest<br /> {<br /> /**//// <summary><br /> /// 表示一類帶動畫功能的映像。<br /> /// </summary><br /> public class AnimateImage<br /> {<br /> Image image;<br /> FrameDimension frameDimension;<br /> /**//// <summary><br /> /// 動畫當前幀發生改變時觸發。<br /> /// </summary><br /> public event EventHandler<EventArgs> OnFrameChanged; </p><p> /**//// <summary><br /> /// 執行個體化一個AnimateImage。<br /> /// </summary><br /> /// <param name="img">動畫圖片。</param><br /> public AnimateImage(Image img)<br /> {<br /> image = img;<br /> lock (image)<br /> {<br /> mCanAnimate = ImageAnimator.CanAnimate(image);<br /> if (mCanAnimate)<br /> {<br /> Guid[] guid = image.FrameDimensionsList;<br /> mFrameCount = image.GetFrameCount(frameDimension);<br /> }<br /> }<br /> } </p><p> bool mCanAnimate;<br /> int mFrameCount = 1, mCurrentFrame = 0; </p><p> /**//// <summary><br /> /// 圖片。<br /> /// </summary><br /> public Image Image<br /> {<br /> get { return image; }<br /> } </p><p> /**//// <summary><br /> /// 是否動畫。<br /> /// </summary><br /> public bool CanAnimate<br /> {<br /> get { return mCanAnimate; }<br /> } </p><p> /**//// <summary><br /> /// 總幀數。<br /> /// </summary><br /> public int FrameCount<br /> {<br /> get { return mFrameCount; }<br /> } </p><p> /**//// <summary><br /> /// 播放的當前幀。<br /> /// </summary><br /> public int CurrentFrame<br /> {<br /> get { return mCurrentFrame; }<br /> }<br /> /**//// <summary><br /> /// 播放這個動畫。<br /> /// </summary><br /> public void Play()<br /> {<br /> if (mCanAnimate)<br /> {<br /> lock (image)<br /> {<br /> ImageAnimator.Animate(image, new EventHandler(FrameChanged));<br /> }<br /> }<br /> } </p><p> /**//// <summary><br /> /// 停止播放。<br /> /// </summary><br /> public void Stop()<br /> {<br /> if (mCanAnimate)<br /> {<br /> lock (image)<br /> {<br /> ImageAnimator.StopAnimate(image, new EventHandler(FrameChanged));<br /> }<br /> }<br /> } </p><p> /**//// <summary><br /> /// 重設動畫,使之停止在第0幀位置上。<br /> /// </summary><br /> public void Reset()<br /> {<br /> if (mCanAnimate)<br /> {<br /> ImageAnimator.StopAnimate(image, new EventHandler(FrameChanged));<br /> lock (image)<br /> {<br /> image.SelectActiveFrame(frameDimension, 0);<br /> mCurrentFrame = 0;<br /> }<br /> }<br /> } </p><p> private void FrameChanged(object sender, EventArgs e)<br /> {<br /> mCurrentFrame = mCurrentFrame + 1 >= mFrameCount ? 0 : mCurrentFrame + 1;<br /> lock (image)<br /> {<br /> image.SelectActiveFrame(frameDimension, mCurrentFrame);<br /> }<br /> if (OnFrameChanged != null)<br /> {<br /> OnFrameChanged(image, e);<br /> }<br /> }<br /> }<br />}

使用如下方法調用:

using System;<br />using System.Collections.Generic;<br />using System.ComponentModel;<br />using System.Data;<br />using System.Drawing;<br />using System.Drawing.Imaging;<br />using System.Text;<br />using System.Windows.Forms; </p><p>namespace GifTest<br />{<br /> public partial class Form1 : Form<br /> {<br /> AnimateImage image; </p><p> public Form1()<br /> {<br /> InitializeComponent();<br /> image = new AnimateImage(Image.FromFile(@"C:/Documents and Settings/Administrator/My Documents/My Pictures/未命名.gif"));<br /> image.OnFrameChanged += new EventHandler<EventArgs>(image_OnFrameChanged);<br /> SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);<br /> } </p><p> void image_OnFrameChanged(object sender, EventArgs e)<br /> {<br /> Invalidate();<br /> } </p><p> private void Form1_Load(object sender, EventArgs e)<br /> {<br /> image.Play();<br /> } </p><p> private void Form1_Paint(object sender, PaintEventArgs e)<br /> {<br /> lock (image.Image)<br /> {<br /> e.Graphics.DrawImage(image.Image, new Point(0, 0));<br /> }<br /> } </p><p> private void button1_Click(object sender, EventArgs e)<br /> {<br /> if (button1.Text.Equals("Stop"))<br /> {<br /> image.Stop();<br /> button1.Text = "Play";<br /> }<br /> else<br /> {<br /> image.Play();<br /> button1.Text = "Stop";<br /> }<br /> Invalidate();<br /> } </p><p> private void button2_Click(object sender, EventArgs e)<br /> {<br /> image.Reset();<br /> button1.Text = "Play";<br /> Invalidate();<br /> }<br /> }<br />}<br />

轉自:http://www.cnblogs.com/cpw999cn/archive/2009/02/07/1385885.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.