部分内容参考博文WPF 如何显示gif

一、使用Storyboard

效果:

(1)页面xaml:

<Window x:Class="PlayGifDemo.StoryboardWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PlayGifDemo"
mc:Ignorable="d"
Title="StoryboardWindow" Height="400" Width="400" WindowStartupLocation="CenterScreen">
<Grid>
<Image x:Name="imgGifShow" Stretch="Fill" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</Window>
(2)后台代码:

/// <summary>
/// StoryboardWindow.xaml 的交互逻辑
/// </summary>
public partial class StoryboardWindow : Window
{
private Storyboard board = null;

public StoryboardWindow()
{
InitializeComponent();
ShowGifByAnimate(@"pack://application:,,,/Resource/loading.gif");
}

/// <summary>
/// 显示GIF动图
/// </summary>
private void ShowGifByAnimate(string filePath)
{
this.Dispatcher.Invoke(() =>
{
List<BitmapFrame> frameList = new List<BitmapFrame>();
GifBitmapDecoder decoder = new GifBitmapDecoder(
new Uri(filePath, UriKind.RelativeOrAbsolute),
BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
if (decoder != null && decoder.Frames != null)
{
frameList.AddRange(decoder.Frames);
ObjectAnimationUsingKeyFrames objKeyAnimate = new ObjectAnimationUsingKeyFrames();
objKeyAnimate.Duration = new Duration(TimeSpan.FromSeconds(1));
foreach (var item in frameList)
{
DiscreteObjectKeyFrame k1_img1 = new DiscreteObjectKeyFrame(item);
objKeyAnimate.KeyFrames.Add(k1_img1);
}
imgGifShow.Source = frameList[0];

board = new Storyboard();
board.RepeatBehavior = RepeatBehavior.Forever;
board.FillBehavior = FillBehavior.HoldEnd;
board.Children.Add(objKeyAnimate);
Storyboard.SetTarget(objKeyAnimate, imgGifShow);
Storyboard.SetTargetProperty(objKeyAnimate, new PropertyPath("(Image.Source)"));
board.Begin();
}
});
}
}
二、使用WpfAnimatedGif

效果:

(1)NuGet包管理器安装WpfAnimatedGif

(2)页面xaml:

<Window x:Class="PlayGifDemo.WpfAnimatedGifWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PlayGifDemo"
xmlns:gif="http://wpfanimatedgif.codeplex.com"
mc:Ignorable="d"
Title="WpfAnimatedGifWindow" Height="400" Width="400" WindowStartupLocation="CenterScreen">
<Grid>
<Image gif:ImageBehavior.AnimatedSource="Resource/loading.gif" />
</Grid>
</Window>
三、使用ImageAnimator

效果:

(1)页面xaml:

<Window x:Class="PlayGifDemo.ImageAnimatorWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PlayGifDemo"
mc:Ignorable="d"
Closing="Window_Closing"
Title="ImageAnimatorWindow" Height="400" Width="400" WindowStartupLocation="CenterScreen">
<Grid>
<Image x:Name="imgGifShow" Stretch="Fill" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</Window>
(2)后台代码:

/// <summary>
/// ImageAnimatorWindow.xaml 的交互逻辑
/// </summary>
public partial class ImageAnimatorWindow : Window
{
private Bitmap gifBitmap;// gif动画的System.Drawing.Bitmap
private BitmapSource bitmapSource;// 用于显示每一帧的BitmapSource

public ImageAnimatorWindow()
{
InitializeComponent();
GetGifImage(AppDomain.CurrentDomain.BaseDirectory + @"/Resource/loading.gif");
}

private void GetGifImage(string path)
{
this.gifBitmap = new Bitmap(path);
this.bitmapSource = this.GetBitmapSource();
this.imgGifShow.Source = this.bitmapSource;
StartAnimate();
}

/// <summary>
/// 从System.Drawing.Bitmap中获得用于显示的那一帧图像的BitmapSource
/// </summary>
/// <returns></returns>
private BitmapSource GetBitmapSource()
{
IntPtr handle = IntPtr.Zero;
try
{
handle = this.gifBitmap.GetHbitmap();
this.bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(handle, IntPtr.Zero, System.Windows.Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
finally
{
if (handle != IntPtr.Zero)
{
DeleteObject(handle);
}
}
return this.bitmapSource;
}

/// <summary>
/// Start
/// </summary>
public void StartAnimate()
{
ImageAnimator.Animate(this.gifBitmap, this.OnFrameChanged);
}

/// <summary>
/// Stop
/// </summary>
public void StopAnimate()
{
ImageAnimator.StopAnimate(this.gifBitmap, this.OnFrameChanged);
}

/// <summary>
/// 帧处理
/// </summary>
private void OnFrameChanged(object sender, EventArgs e)
{
Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
{
ImageAnimator.UpdateFrames(); // 更新到下一帧
if (this.bitmapSource != null)
{
this.bitmapSource.Freeze();
}

this.bitmapSource = this.GetBitmapSource();
this.imgGifShow.Source = this.bitmapSource;
this.InvalidateVisual();
}));
}

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
StopAnimate();
}

/// <summary>
/// 删除本地 bitmap resource
/// </summary>
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool DeleteObject(IntPtr hObject);
}
四、使用Winform控件PictureBox

效果:

(1)添加对System.Windows.Forms.dll、WindowsFormsIntegration.dll、System.Drawing.dll的引用

(2)页面xaml:

<Window x:Class="PlayGifDemo.PictureBoxWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PlayGifDemo"
xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
xmlns:winForms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
mc:Ignorable="d"
Loaded="Window_Loaded"
Title="PictureBoxWindow" Height="400" Width="400" WindowStartupLocation="CenterScreen">
<Grid>
<wfi:WindowsFormsHost>
<winForms:PictureBox x:Name="pictureGifShow"></winForms:PictureBox>
</wfi:WindowsFormsHost>
</Grid>
</Window>
(3)后台代码:

/// <summary>
/// PictureBoxWindow.xaml 的交互逻辑
/// </summary>
public partial class PictureBoxWindow : Window
{
public PictureBoxWindow()
{
InitializeComponent();
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.pictureGifShow.Image = System.Drawing.Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + @"/Resource/loading.gif");
this.pictureGifShow.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
}
}
五、使用MediaElement

效果(采用MediaElement控件这种方式播放背景底色默认是黑色):

(1)页面xaml:

<Window x:Class="PlayGifDemo.MediaElementWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PlayGifDemo"
mc:Ignorable="d"
Loaded="Window_Loaded"
Title="MediaElementWindow" Height="400" Width="400" WindowStartupLocation="CenterScreen">
<Grid>
<MediaElement Name="mediaGifShow" MediaEnded="MediaElement_MediaEnded" Stretch="Fill"/>
</Grid>
</Window>
(2)后台代码:

/// <summary>
/// MediaElementWindow.xaml 的交互逻辑
/// </summary>
public partial class MediaElementWindow : Window
{
public MediaElementWindow()
{
InitializeComponent();
}

private void MediaElement_MediaEnded(object sender, RoutedEventArgs e)
{
((MediaElement)sender).Position = ((MediaElement)sender).Position.Add(TimeSpan.FromMilliseconds(1));
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.mediaGifShow.Source = new Uri(AppDomain.CurrentDomain.BaseDirectory + @"/Resource/loading.gif");
}
}

————————————————
版权声明:本文为CSDN博主「RunnerDNA」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/dnazhd/article/details/105736989

WPF加载GIF的五种方式(Storyboard / WpfAnimatedGif / ImageAnimator / PictureBox / MediaElement)的更多相关文章

  1. JavaScript判断图片是否加载完成的三种方式

    JavaScript判断图片是否加载完成的三种方式 有时需要获取图片的尺寸,这需要在图片加载完成以后才可以.有三种方式实现,下面一一介绍. 一.load事件 1 2 3 4 5 6 7 8 9 10 ...

  2. jsp页面加载readyState的五种状态根据我们状态添加进度条

    这段代码放在页面最下面 原文如下: document.onreadystatechange = subSomething;//当页面加载状态改变的时候执行这个方法. function subSomet ...

  3. WebView加载页面的两种方式——网络页面和本地页面

    WebView加载页面的两种方式 一.加载网络页面 加载网络页面,是最简单的一种方式,只需要传入http的URL就可以,实现WebView加载网络页面 代码如下图: 二.加载本地页面 1.加载asse ...

  4. [Android] Android ViewPager 中加载 Fragment的两种方式 方式(二)

    接上文: https://www.cnblogs.com/wukong1688/p/10693338.html Android ViewPager 中加载 Fragmenet的两种方式 方式(一) 二 ...

  5. [Android] Android ViewPager 中加载 Fragment的两种方式 方式(一)

    Android ViewPager 中加载 Fragmenet的两种方式 一.当fragment里面的内容较少时,直接 使用fragment xml布局文件填充 文件总数 布局文件:view_one. ...

  6. Vue加载组件、动态加载组件的几种方式

    https://cn.vuejs.org/v2/guide/components.html https://cn.vuejs.org/v2/guide/components-dynamic-async ...

  7. VUE 动态加载组件的四种方式

    动态加载组件的四种方式: 1.使用import导入组件,可以获取到组件 var name = 'system'; var myComponent =() => import('../compon ...

  8. 加载映射文件几种方式和mapper接口注解执行sql语句

    一.加载映射文件几种方式 二.mapper接口注解执行sql语句 就将xml中的sql语句放到注解的括号中就可以,一般只用于简单的sql语句合适:

  9. 让浏览器非阻塞加载javascript的几种方式

    通常大多数浏览器是并行下载资源的,但由于外部脚本的特殊性例如通过脚本改变文档的DOM结构.脚本之间的存在依赖关系.使用document.write 向页面输出HTML等.浏览器为了确保正确执行脚本和呈 ...

  10. 从Xib文件加载UIView的5种方式

    在不同的Xib文件中最容易维护的是定义的视图,因此对于从Xib文件中加载UIView来说一个方便的流程是非常重要. 在过去的几年里我发现唯一易于管理创建和维护视图(或者任何界面元素,通常会更多)方式就 ...

随机推荐

  1. Windows Server 2008 R2修复永恒之蓝漏洞

    一.情况描述 服务器安装的Windows Server 2008 R2 standard系统,通过扫描发现系统存在永恒之蓝漏洞MS17-010(CVE-2017-0143.CVE-2017-0144. ...

  2. redis哨兵主备切换的数据丢失问题:异步复制、集群脑裂

    1.两种数据丢失的情况 主备切换的过程,可能会导致数据丢失 (1)异步复制导致的数据丢失 因为master -> slave的复制是异步的,所以可能有部分数据还没复制到slave,master就 ...

  3. 龙湖千丁基于 ACK@Edge 的云原生智慧停车系统架构实践

    简介: 结合龙湖千丁自研的新版停车云系统以及 ACK@Edge 提供的标准 Kubernetes 服务以及云边一体化协同解决方案,整体来着,边缘部署时间成本由 1 天缩短到 3 小时,将之前的手动升级 ...

  4. 作业帮在线业务 Kubernetes Serverless 虚拟节点大规模应用实践

    ​简介:目前方案已经成熟,高峰期已有近万核规模的核心链路在线业务运行在基于阿里云 ACK+ECI 的 Kubernetes Serverless 虚拟节点.随着业务的放量,未来运行在 Serverle ...

  5. 阿里开源自研工业级稀疏模型高性能训练框架 PAI-HybridBackend

    ​简介:近年来,随着稀疏模型对算力日益增长的需求, CPU集群必须不断扩大集群规模来满足训练的时效需求,这同时也带来了不断上升的资源成本以及实验的调试成本.为了解决这一问题,阿里云机器学习PAI平台开 ...

  6. 大数据时代下的App数据隐私安全

    ​简介:随着信息技术快速发展,大数据为我们带来信息共享.便捷生活的同时,还存在着数据安全问题,主流商业模式下APP面临新的挑战.工信部持续开展APP侵权整治活动,进行了了六批次集中抽检,检查了76万款 ...

  7. OpenKruise v1.0:云原生应用自动化达到新的高峰

    ​简介:OpenKruise 是针对 Kubernetes 的增强能力套件,聚焦于云原生应用的部署.升级.运维.稳定性防护等领域. 云原生应用自动化管理套件.CNCF Sandbox 项目 -- Op ...

  8. Dubbo 跨语言调用神兽:dubbo-go-pixiu

    简介: Pixiu 是基于 Dubbogo 的云原生.高性能.可扩展的微服务 API 网关.作为一款网关产品,Pixiu 帮助用户轻松创建.发布.维护.监控和保护任意规模的 API ,接受和处理成千上 ...

  9. [DApp] ethers.js VS Moralis

    ether.js 是 Web3 封装的 js 库,特别适合以太坊平台. Moralis 不仅是 Web3 的封装,还是一体化解决方案,包括服务端部署方案和适配各种链,使用范围更广. 在选择上,主要还是 ...

  10. 21.3K star!推荐一款可视化自动化测试/爬虫/数据采集神器!功能免费且强大!

    大家好,我是狂师! 在大数据时代,信息的获取与分析变得尤为重要.对于开发者.数据分析师乃至非技术人员来说,能够高效地采集网络数据并进行分析是一个强有力的工具.今天,我要向大家推荐的是一款功能强大.操作 ...