C# Winform中如何绘制动画示例详解

 更新时间:2020年05月14日 08:48:50   作者:小y  
这篇文章主要给大家介绍了关于C# Winform中如何绘制动画的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用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();  
    }  
  }  
}

总结

到此这篇关于C# Winform中如何绘制动画的文章就介绍到这了,更多相关C# Winform绘制动画内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C# Winfrom实现Skyline画直线功能的示例代码

    C# Winfrom实现Skyline画直线功能的示例代码

    这篇文章主要介绍了C# Winfrom实现Skyline画直线功能的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • C# 可空类型的实现示例

    C# 可空类型的实现示例

    本文主要介绍了C#中的可空类型,包含单问号(?)和双问号(??),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-11-11
  • C#实现五子棋游戏

    C#实现五子棋游戏

    这篇文章主要为大家详细介绍了C#实现五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • C#爬虫基础之HttpClient获取HTTP请求与响应

    C#爬虫基础之HttpClient获取HTTP请求与响应

    这篇文章介绍了C#使用HttpClient获取HTTP请求与响应的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • WPF实现好看的Loading动画的示例代码

    WPF实现好看的Loading动画的示例代码

    这篇文章主要介绍了如何利用WPF实现好看的Loading动画效果,文中的示例代码讲解详细,对我们学习或工作有一定帮助,需要的可以参考一下
    2022-08-08
  • c# 使用Json.NET实现json序列化

    c# 使用Json.NET实现json序列化

    这篇文章主要介绍了详解C#中的JSON序列化方法,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-05-05
  • C# 如何添加错误日志信息

    C# 如何添加错误日志信息

    这篇文章主要介绍了C# 如何添加错误日志信息,错误日志是软件用来记录运行时出错信息的文本文件。编程人员和维护人员等可以利用错误日志对系统进行调试和维护。
    2020-11-11
  • C#调用python脚本的方法详解

    C#调用python脚本的方法详解

    这篇文章主要为大家详细介绍了C#调用python脚本的方法,文中通过示例代码介绍的非常详细,感兴趣的朋友们下面随着小编来一起学习学习吧
    2023-11-11
  • C#实现的简单验证码识别实例

    C#实现的简单验证码识别实例

    这篇文章主要介绍了C#实现的简单验证码识别实例,只适应一些简单的验证码,需要的朋友可以参考下
    2014-06-06
  • C#中接口的显式实现与隐式实现及其相关应用案例详解

    C#中接口的显式实现与隐式实现及其相关应用案例详解

    最近在学习演化一款游戏项目框架时候,框架作者巧妙使用接口中方法的显式实现来变相对接口中方法进行“密封”,增加实现接口的类访问方法的“成本”,这篇文章主要介绍了C#中接口的显式实现与隐式实现及其相关应用案例,需要的朋友可以参考下
    2024-05-05

最新评论