C# Winform中如何绘制动画示例详解
作者:小y 时间:2022-03-28 13:26:26
前言
这里介绍一个.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();
}
}
}
来源:https://www.cnblogs.com/tuyile006/p/12880641.html
标签:c#,winform,动画
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Java中List集合去重方法以及效率对比
2021-11-03 00:15:52
Java中逆序遍历List集合的实现
2022-04-03 23:48:13
![](https://img.aspxhome.com/file/2023/4/62114_0s.png)
Java中URL传中文时乱码的解决方法
2022-05-17 02:16:55
C#控制图像旋转和翻转的方法
2023-11-26 08:25:08
Java设计模式之工厂模式案例详解
2023-11-27 20:08:03
![](https://img.aspxhome.com/file/2023/2/60342_0s.png)
Java编程中使用throw关键字抛出异常的用法简介
2023-08-27 17:04:19
![](https://img.aspxhome.com/file/2023/9/58209_0s.png)
Java中this和super的区别及this能否调用到父类使用
2023-01-05 12:03:13
![](https://img.aspxhome.com/file/2023/6/61876_0s.webp)
PyQt5内嵌浏览器注入JavaScript脚本实现自动化操作的代码实例
2023-11-26 15:05:59
java动态口令登录实现过程详解
2022-01-01 10:16:28
微信开发--自定义菜单查询返码乱码的解决方法
2023-11-25 04:47:55
Spring的初始化和XML解析的实现
2022-12-13 15:50:51
SpringBoot集成内存数据库H2的实践
2023-03-20 22:44:34
![](https://img.aspxhome.com/file/2023/5/63405_0s.png)
一篇文章带你了解JAVA结构化编程详情
2022-01-15 13:06:34
永久解决idea git log乱码的问题
2022-01-10 06:13:13
![](https://img.aspxhome.com/file/2023/4/63434_0s.jpg)
如何在C#9 中使用顶级程序 (top-level)
2023-08-20 04:13:24
![](https://img.aspxhome.com/file/2023/2/79052_0s.jpg)
微信跳一跳辅助Java代码实现
2022-03-31 19:12:03
Java实现通讯录管理系统项目
2022-11-17 02:41:03
![](https://img.aspxhome.com/file/2023/3/71903_0s.jpg)
C#实现获取程序路径方法小结
2022-05-09 19:40:48
c#多线程编程基础
2021-11-24 23:37:12
阿里云OSS域名配置及简单上传的示例代码
2022-04-08 19:14:32
![](https://img.aspxhome.com/file/2023/1/79211_0s.png)