【学习笔记】Windows GDI绘图(十三)动画播放ImageAnimator(可调速)

本文主要是介绍【学习笔记】Windows GDI绘图(十三)动画播放ImageAnimator(可调速),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 定义
  • 方法
    • CanAnimate 是否可动画显示
    • Animate 动画显示多帧图像
    • UpdateFrames
    • StopAnimate终止动画
    • Image.GetFrameCount 获取动画总帧数
    • Image.GetPropertyItem(0x5100) 获取帧延迟
  • 自定义GIF播放(可调速)

前言

在前一篇文章中用到ImageAnimator获取了GIF动画的一些属性,但没有真正使用ImageAnimator来进行GIF动画播放(还可能误导),所有这篇就深入了解ImageAnimator的使用。
本文使用的动画为另一篇文章 心动(GDI+) 使用 GDI+纯手工绘制生成,有兴趣的可以查看原文,并配原码。

定义

public sealed class ImageAnimator

作用:对具有基于时间帧的图像进行动画显示。

方法

CanAnimate 是否可动画显示

原型:

public static bool CanAnimate (System.Drawing.Image image);

作用:判断指定图像是否包含基于时间帧。

Animate 动画显示多帧图像

原型:

public static void Animate (System.Drawing.Image image, EventHandler onFrameChangedHandler);

作用:将多帧图像显示为动画。

UpdateFrames

原型:

public static void UpdateFrames ();
public static void UpdateFrames (System.Drawing.Image image);

作用:使多帧动画前推进,下次渲染时,使用新的图像。

1、加载一个动画Image.FromFile
2、判断该图像是基于时间帧的图像 CanAnimate
3、指定帧切换事件 Animate
4、推进多帧动画
5、绘制最新图像

private Image gifImg = null;
/// <summary>
/// 加载多帧图像
/// </summary>
private void LoadGif()
{gifImg = Image.FromFile("Heartbeat.gif");if (ImageAnimator.CanAnimate(gifImg)){ImageAnimator.Animate(gifImg, OnFrameChanged);}
}
//切换帧事件
private void OnFrameChanged(object o, EventArgs e)
{//强制显示this.paintCtrl_Main.Panel_Main.Invalidate();
}[System.ComponentModel.Description("ImageAnimator的Animate方法")]
public void Demo13_01(PaintEventArgs e)
{if (gifImg == null){LoadGif();}ImageAnimator.UpdateFrames(gifImg);e.Graphics.DrawImage(gifImg, 0, 0, this.paintCtrl_Main.Panel_Main.Width, this.paintCtrl_Main.Panel_Main.Height);
}

由以上代码,使用ImageAnimator加GDI+绘制,可以很容易实现GIF动画的播放。
Gif动画播放

StopAnimate终止动画

原型:

public static void StopAnimate (System.Drawing.Image image, EventHandler onFrameChangedHandler);

作用:停止动画显示。(实际上没有真正停止,还需要其他条件配合)

private Image gifImg = null;
EventHandler OnFrameChangedEventHandler;
/// <summary>
/// 加载多帧图像
/// </summary>
private void LoadGif()
{gifImg = Image.FromFile("Heartbeat.gif");if (ImageAnimator.CanAnimate(gifImg)){OnFrameChangedEventHandler = new EventHandler(OnFrameChanged);isStop = false;ImageAnimator.Animate(gifImg, OnFrameChangedEventHandler);this.paintCtrl_Main.Panel_Main.Click += PaintCtrl_Main_Click; ;}
}private void PaintCtrl_Main_Click(object sender, EventArgs e)
{if (isStop){ImageAnimator.Animate(gifImg, OnFrameChangedEventHandler);}else{ImageAnimator.StopAnimate(gifImage, OnFrameChangedEventHandler);}isStop = !isStop;
}private bool isStop = false;
private void OnFrameChangedStop(object o, EventArgs e)
{isStop = true;
}//切换帧事件
private void OnFrameChanged(object o, EventArgs e)
{//强制显示this.paintCtrl_Main.Panel_Main.Invalidate();
}[System.ComponentModel.Description("ImageAnimator的Animate方法")]
public void Demo13_01(PaintEventArgs e)
{if (gifImg == null){LoadGif();}if (!isStop){ImageAnimator.UpdateFrames(gifImg);}e.Graphics.DrawImage(gifImg, 0, 0, this.paintCtrl_Main.Panel_Main.Width,this.paintCtrl_Main.Panel_Main.Height);
}

通过鼠标点击,控制Gif动画开始,还是停止。

Image.GetFrameCount 获取动画总帧数

原型:

public int GetFrameCount (System.Drawing.Imaging.FrameDimension dimension);

作用:返回指定维度的帧数。

Image.GetPropertyItem(0x5100) 获取帧延迟

作用:返回每帧的延迟数

/// <summary>
/// 获取帧总数、帧延迟
/// </summary>
private void GetFrameDelays()
{//总帧数var frameCount = gifImg.GetFrameCount(FrameDimension.Time);var frameDelay = gifImg.GetPropertyItem(0x5100);//FrameDelay 帧延迟//var loopCount= gifImg.GetPropertyItem(0x5110);//LoopCount GIF循环计数byte[] values = frameDelay.Value;// 每个延迟时间占 4 个字节var frameDelays = new int[frameCount];for (int i = 0; i < frameCount; i++){frameDelays[i] = BitConverter.ToInt32(values, i * 4) * 10; // 单位是 1/100 秒,转换为毫秒}
}

自定义GIF播放(可调速)

使用ImageAnimator的Animate的速度由Gif内置的每帧时间延迟控制,具体可见GetFrameDelays函数示例。如果需要实现自定义速度播放,可使用Timer来控制播放速度。
1、使用Image.FromFile加载Gif动画
2、用ImageAnimator.CanAnimate判断是否为多帧动画
3、获取Gif动画的FrameDimension和总帧数
4、定义并启用一个Timer,设置Interval控制播放速度
5、设置Timer.Tick函数,切换当前帧数和强制控件刷新
6、设置控件MouseClick事件,左键timer.Interval减小,右键Interval加大
7、在Paint事件中SelectActiveFrame激活指定帧,然后绘制

[System.ComponentModel.Description("ImageAnimator的GIF动画播放可调速")]
public void Demo13_02(PaintEventArgs e)
{if (gifImg == null){LoadGif2();}if (FrameCount > 0){gifImg.SelectActiveFrame(dimension, currentFrame);e.Graphics.DrawImage(gifImg, 0, 0, gifImg.Width, gifImg.Height);e.Graphics.DrawString($"左键加速/右键减速 {1000 / GifTimer.Interval}帧/秒,当前帧:{currentFrame}", Font, Brushes.Red, new PointF(20, 20));}
}FrameDimension dimension;
/// <summary>
/// 加载多帧图像
/// </summary>
private void LoadGif2()
{gifImg = Image.FromFile("Heartbeat.gif");if (ImageAnimator.CanAnimate(gifImg)){dimension = new FrameDimension(gifImg.FrameDimensionsList[0]);FrameCount = gifImg.GetFrameCount(dimension);GifTimer = new Timer();GifTimer.Interval = 40;GifTimer.Tick += OnTick;GifTimer.Start();this.paintCtrl_Main.Panel_Main.MouseClick += Panel_Main_MouseClick;}
}
private int currentFrame = 0;
/// <summary>
/// 切换当前帧数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnTick(object sender, EventArgs e)
{currentFrame = (currentFrame + 1) % FrameCount;this.paintCtrl_Main.Panel_Main.Invalidate();
}private Timer GifTimer;
//加/减速
private void Panel_Main_MouseClick(object sender, MouseEventArgs e)
{if (e.Button == MouseButtons.Right){GifTimer.Interval *= 2;}else{var interval = GifTimer.Interval / 2;if (interval < 1){interval = 1;}GifTimer.Interval = interval;}
}
int FrameCount = 0;

使用Timer控制Gif播放

这篇关于【学习笔记】Windows GDI绘图(十三)动画播放ImageAnimator(可调速)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1041359

相关文章

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

Windows设置nginx启动端口的方法

《Windows设置nginx启动端口的方法》在服务器配置与开发过程中,nginx作为一款高效的HTTP和反向代理服务器,被广泛应用,而在Windows系统中,合理设置nginx的启动端口,是确保其正... 目录一、为什么要设置 nginx 启动端口二、设置步骤三、常见问题及解决一、为什么要设置 nginx

Python实现多路视频多窗口播放功能

《Python实现多路视频多窗口播放功能》这篇文章主要为大家详细介绍了Python实现多路视频多窗口播放功能的相关知识,文中的示例代码讲解详细,有需要的小伙伴可以跟随小编一起学习一下... 目录一、python实现多路视频播放功能二、代码实现三、打包代码实现总结一、python实现多路视频播放功能服务端开

在 Windows 上安装 DeepSeek 的完整指南(最新推荐)

《在Windows上安装DeepSeek的完整指南(最新推荐)》在Windows上安装DeepSeek的完整指南,包括下载和安装Ollama、下载DeepSeekRXNUMX模型、运行Deep... 目录在www.chinasem.cn Windows 上安装 DeepSeek 的完整指南步骤 1:下载并安装

windows系统下shutdown重启关机命令超详细教程

《windows系统下shutdown重启关机命令超详细教程》shutdown命令是一个强大的工具,允许你通过命令行快速完成关机、重启或注销操作,本文将为你详细解析shutdown命令的使用方法,并提... 目录一、shutdown 命令简介二、shutdown 命令的基本用法三、远程关机与重启四、实际应用

Windows自动化Python pyautogui RPA操作实现

《Windows自动化PythonpyautoguiRPA操作实现》本文详细介绍了使用Python的pyautogui库进行Windows自动化操作的实现方法,文中通过示例代码介绍的非常详细,对大... 目录依赖包睡眠:鼠标事件:杀死进程:获取所有窗口的名称:显示窗口:根据图片找元素:输入文字:打开应用:依

最好用的WPF加载动画功能

《最好用的WPF加载动画功能》当开发应用程序时,提供良好的用户体验(UX)是至关重要的,加载动画作为一种有效的沟通工具,它不仅能告知用户系统正在工作,还能够通过视觉上的吸引力来增强整体用户体验,本文给... 目录前言需求分析高级用法综合案例总结最后前言当开发应用程序时,提供良好的用户体验(UX)是至关重要

javafx 如何将项目打包为 Windows 的可执行文件exe

《javafx如何将项目打包为Windows的可执行文件exe》文章介绍了三种将JavaFX项目打包为.exe文件的方法:方法1使用jpackage(适用于JDK14及以上版本),方法2使用La... 目录方法 1:使用 jpackage(适用于 JDK 14 及更高版本)方法 2:使用 Launch4j(

基于Python实现PDF动画翻页效果的阅读器

《基于Python实现PDF动画翻页效果的阅读器》在这篇博客中,我们将深入分析一个基于wxPython实现的PDF阅读器程序,该程序支持加载PDF文件并显示页面内容,同时支持页面切换动画效果,文中有详... 目录全部代码代码结构初始化 UI 界面加载 PDF 文件显示 PDF 页面页面切换动画运行效果总结主

windows端python版本管理工具pyenv-win安装使用

《windows端python版本管理工具pyenv-win安装使用》:本文主要介绍如何通过git方式下载和配置pyenv-win,包括下载、克隆仓库、配置环境变量等步骤,同时还详细介绍了如何使用... 目录pyenv-win 下载配置环境变量使用 pyenv-win 管理 python 版本一、安装 和