前言
本文告诉大家如何在 WPF 播放 Gif 图片,提供了几个方法进行播放,包括比较性能。
1.MediaElement 方法
2.GifBitmapDecoder 方法
3.Magick 方法
4.WinForm 的方法
MediaElement 方法
-
这是比较不推荐的方法,但是使用简单
<MediaElement x:Name="gifMedia" Source="x.gif" UnloadedBehavior="Manual" LoadedBehavior="Play" />
GifBitmapDecoder 方法
-
使用 GifBitmapDecoder 能用上 WIC 层系统解码,能支持很多奇怪的格式,以下是我实现的版本,我实现的版本只能播放简单的全画的 GIF 图片
WPF 通过 GifBitmapDecoder 调用 WIC 解析 Gif 和进行动画播放的简单方法[1]
Magick 方法
-
这个方法请参见博客 WPF一个性能比较好的gif解析库[2]
WinForm 的方法
-
使用
-
本文提供的类,可以直接在 Xaml 使用或者在 cs 使用,可以控制开始播放和停止。
-
在播放的过程中,使用很少的内存。在使用到一定的时间,会自动释放内存。而且比我现在项目使用的播放的 CPU 要少很多,我自己写的 gif 播放需要使用 3% 左右的 CPU,下面这个类使用的 CPU 只有 1% 。当然我的 gif 解析使用的内存会比下面的代码少,不然我就不敢把下面的代码开源了
-
在 xaml 使用的方法:
<local:GifImageControl x:Name="Image" Path="2017年3月23日 115958.gif"></local:GifImageControl>
-
在添加进之后就会自动开始播放 -
如果需要在后台代码添加,那么可以使用下面代码
<Grid x:Name="HlosqrrsDnqxv">
</Grid>
var image = new GifImageControl("2017年3月23日 115958.gif");
HlosqrrsDnqxv.Children.Add(image);
-
因为代码很简单,所以需要其他的功能,请看源代码
源码
-
代码放在 github ,可以直接复制这个类到工程使用。下面代码可以用在正式项目中。
/// <summary>
/// 使用 WinForm 播放 Gif
/// </summary>
/// <example>
/// xaml:
/// <local:GifImageControl x:Name="Image" Path="lindexi.gif"></local:GifImageControl>
/// cs:
/// var image = new GifImageControl("E:\lindexi.gif");
/// Grid.Children.Add(image);
/// </example>
public class GifImageControl : Image
{
/// <inheritdoc />
public GifImageControl()
{
}
/// <inheritdoc />
public GifImageControl(string path)
{
Path = path;
}
/// <summary>
/// 图片的地址
/// </summary>
public string Path
{
get => _path;
set
{
if (!File.Exists(value))
{
var file = new FileInfo(value);
if (!file.Exists)
{
throw new ArgumentException("找不到文件" + value);
}
value = file.FullName;
}
_path = value;
Start();
}
}
/// <summary>
/// 播放图片
/// </summary>
public void Start()
{
if (_bitmap != null)
{
//多次点击播放,如果没有停止,会让上一个图片还在播放
Stop();
}
var path = Path;
_bitmap = (Bitmap) System.Drawing.Image.FromFile(path);
ImageAnimator.Animate(_bitmap, OnFrameChanged);
_bitmapSource = GetBitmapSource();
Source = _bitmapSource;
}
/// <summary>
/// 停止播放
/// </summary>
public void Stop()
{
if (_bitmap == null)
{
return;
}
ImageAnimator.StopAnimate(_bitmap, OnFrameChanged);
_bitmap.Dispose();
_bitmap = null;
}
private Bitmap _bitmap;
private BitmapSource _bitmapSource;
private string _path;
private void OnFrameChanged(object sender, EventArgs e)
{
Dispatcher.InvokeAsync(OnFrameChangedInMainThread);
}
private void OnFrameChangedInMainThread()
{
ImageAnimator.UpdateFrames();
_bitmapSource = GetBitmapSource();
Source = _bitmapSource;
InvalidateVisual();
}
private BitmapSource GetBitmapSource()
{
IntPtr inptr = _bitmap.GetHbitmap();
_bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(
inptr, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
DeleteObject(inptr);
return _bitmapSource;
}
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DeleteObject(IntPtr hObject);
}
-
如果在运行项目出现 异常,那么请把 DeleteObject 方法修改为下面的代码
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DeleteObject(IntPtr hObject);
-
打开 .sln 文件,然后按 F5 运行,可以看到占用内存在 120M ,在运行一定时间,回收内存,占用内存70M,而CPU几乎都不需要。WPF播放GIF控件完整代码 – CSDN博客[3] -
如果在运行出现任何问题,请告诉我,上面这个方法不保证可以解决任何的gif图片。
参考资料
WPF 通过 GifBitmapDecoder 调用 WIC 解析 Gif 和进行动画播放的简单方法: https://blog.lindexi.com/post/WPF-%E9%80%9A%E8%BF%87-GifBitmapDecoder-%E8%B0%83%E7%94%A8-WIC-%E8%A7%A3%E6%9E%90-Gif-%E5%92%8C%E8%BF%9B%E8%A1%8C%E5%8A%A8%E7%94%BB%E6%92%AD%E6%94%BE%E7%9A%84%E7%AE%80%E5%8D%95%E6%96%B9%E6%B3%95.html
[2]
WPF一个性能比较好的gif解析库: https://lindexi.gitee.io/post/WPF-%E4%B8%80%E4%B8%AA%E6%80%A7%E8%83%BD%E6%AF%94%E8%BE%83%E5%A5%BD%E7%9A%84-gif-%E8%A7%A3%E6%9E%90%E5%BA%93.html
[3]
WPF播放GIF控件完整代码 – CSDN博客: https://blog.csdn.net/Libby1984/article/details/52535085
原文始发于微信公众号(WPF开发者):WPF 播放 gif
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/55226.html