部分内容参考博文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. 实时 3D 深度多摄像头跟踪 Real-time 3D Deep Multi-Camera Tracking

    实时 3D 深度多摄像头跟踪 Real-time 3D Deep Multi-Camera Tracking 论文url https://arxiv.org/abs/2003.11753 论文简述: ...

  2. 打造美团外卖新体验,HarmonyOS SDK 持续赋能开发者共赢鸿蒙生态

    从今年 8 月起,所有升级到 HarmonyOS 4 的手机用户在美团外卖下单后,可通过屏幕上的一个"小窗口",随时追踪到"出餐.取餐.送达"等订单状态.这个能 ...

  3. pyaudio音频录制python

    python3.7不支持pyaudio pip在线安装 whl下载地址:https://github.com/intxcc/pyaudio_portaudio/releases 下载后使用pip离线安 ...

  4. 建设工程工程量清单计价规范2008最新分析报告ppt

    2008版<计价规范>颁布的背景 国务院从2003年起,在全国范围开展清理拖欠工程款.清理拖欠农民工工资的活动.最高人民法院于2004年9月29日发布了<关于审理建设工程施工合同纠纷 ...

  5. AI极速批量换脸!Roop-unleashed下载介绍,可直播

    要说AI换脸领域,最开始火的项目就是Roop了,Roop-unleashed作为Roop的嫡系分支,不仅继承了前者的强大基因,更是在功能上实现了重大突破与升级 核心特性 1.可以进行高精度的图片.视频 ...

  6. 力扣615(MySQL)-平均工资:部门与公司比较(困难)

    题目: 给如下两个表,写一个查询语句,求出在每一个工资发放日,每个部门的平均工资与公司的平均工资的比较结果 (高 / 低 / 相同). 表: salary employee_id 字段是表 emplo ...

  7. 第 7章 Python 爬虫框架 Scrapy(上)

    第 7章 Python 爬虫框架 Scrapy(上) 编写爬虫可以看成行军打仗,基本的角色有两个:士兵和将军,士兵冲锋陷阵,而将军更多地是调兵遣将.框架就像一个将军,里面包含了爬虫的全部流程.异常处理 ...

  8. 5款开源、美观、强大的WPF UI组件库

    前言 经常看到有小伙伴在DotNetGuide技术社区交流群里提问:WPF有什么好用或者好看的UI组件库?,今天大姚给大家分享5款开源.美观.强大.简单易用的WPF UI组件库. WPF介绍 WPF ...

  9. 最佳实践丨三种典型场景下的云上虚拟IDC(私有池)选购指南

    ​简介:业务上云常态化,业务在云上资源的选购.弹性交付.自助化成为大趋势.不同行业的不同客户,业务发展阶段不一样,云上资源的成本投入在业务整体成本占比也不一样,最小化成本投入.最大化业务收益始终是不同 ...

  10. [Go] golang 执行 Linux 系统 command

    执行系统 shell 命令示例: fileDir := "files/"out, err := exec.Command("sh", "-c" ...