wpf 如何使用 Magick.NET 播放 gif 图片 安装 Magick.NET解析 gif播放 gif

本文告诉大家使用 Magick.NET 的方法播放 gif 图片。

最近在做 gif 播放,发现 gif 播放需要很多内存,于是就使用 Magick.NET 播放,但是这个方式也需要很多的内存。播放一张 uwp 萤火虫 需要 600 M 内存。但是我还是把方法记下。

安装 Magick.NET

可以选择的很多,如果只是做测试,那么建议直接使用 AnyCPU 这样就不需要关心在哪里使用。里面的选项 Qn中的n就是表示质量,一般使用 8 就可以啦。

安装的方法建议使用 nuget 下载,nuget 可以使用国内博客园的源,当然现在大法更新了速度,安装也不难。

解析 gif

安装完成之后就可以使用,不过使用之前需要先设置缓存MagickAnyCPU.CacheDirectory,然后进行解析gif。关于解析参见:WPF 一个性能比较好的 gif 解析库 - 林德熙,这篇文章的解析只能播放常规的 gif ,对于压缩的 gif 是无法进行播放的,如果需要播放压缩后的 gif 那么需要使用 Coalesce ,一旦使用了就需要大概800M的内存,虽然很快就gc了。

常规 gif 图是直接把图片存放,对于这个文件,只需要把他分为多个 图片播放出来就好,需要注意就是他的图片时间,多久才继续播放。解析这个格式很简单,还可以使用大法的[wpf GifBitmapDecoder 解析 gif 格式(https://lindexi.github.io/lindexi/post/wpf-GifBitmapDecoder-%E8%A7%A3%E6%9E%90-gif-%E6%A0%BC%E5%BC%8F.html )

压缩的 gif 是把两个图片,判断这张图片有哪些像素和上一张一样,如果存在,就忽略。这个算法可以减少图片的空间。但是解析难度有些大,因为需要获得播放的上一个图片才可以进行解析这一张图片。

本文的解析gif 方法已经在WPF 一个性能比较好的 gif 解析库 - 林德熙讲到,下面就是代码。

            collection = new MagickImageCollection(File);

播放 gif

这次播放的方式不是使用 image,而是直接写一个底层的控件播放,请看代码

    public class SuxlzHjp : UIElement
    {
        public SuxlzHjp()
        {
            MagickAnyCPU.CacheDirectory = "E:\\temp";
        }

        public void Play()
        {
            if (string.IsNullOrEmpty(CacheDirectory))
            {
                CacheDirectory = Path.Combine(Environment.CurrentDirectory, "temp");
            }
            if (!Directory.Exists(CacheDirectory))
            {
                Directory.CreateDirectory(CacheDirectory);
            }
            MagickAnyCPU.CacheDirectory = CacheDirectory;

            collection = new MagickImageCollection(File);

            int n = 0;
            Task.Run(async () =>
            {
                while (true)
                {
                    if (n == collection.Count)
                    {
                        n = 0;
                    }

                    var t = collection[n];
                    var delay = t.AnimationDelay * 10;

                    await Dispatcher.InvokeAsync(() =>
                    {
                        var width = t.Width;
                        var height = t.Height;
                        RenderTargetBitmap image = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
                        image.Render(drawing);
                        using (var drawingContext = drawing.RenderOpen())
                        {
                            drawingContext.DrawImage(image, new Rect(0, 0, width, height));
                            drawingContext.DrawImage(t.ToBitmapSource(),
                                new Rect(t.BoundingBox.X, t.BoundingBox.Y, t.BoundingBox.Width, t.BoundingBox.Height));
                        }
                        InvalidateVisual();
                    });

                    await Task.Delay(delay);
                    n++;
                }
            });
        }

        public static readonly DependencyProperty FileProperty = DependencyProperty.Register(
            nameof(File), typeof(string), typeof(SuxlzHjp), new PropertyMetadata(default(string)));

        public static string CacheDirectory { get; set; }

        public string File
        {
            get => (string) GetValue(FileProperty);
            set => SetValue(FileProperty, value);
        }


        protected override void OnRender(DrawingContext drawingContext)
        {
            drawingContext.DrawDrawing(drawing.Drawing);
            base.OnRender(drawingContext);
        }

        private DrawingVisual drawing = new DrawingVisual();

        private MagickImageCollection collection;
    }

可以尝试这个类进行播放,使用方法是设置 File 然后Play,可以看到这个方法需要使用的内存有 600M ,还不停gc所以这个方式不是我推荐。

其他播放gif的方法请看WPF 播放 gif


本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏WindCoder

Android学习笔记-控件初体验

python为自己自学的,现仍处于初级阶段,这学期开启的是javaEE和Android开发,所以今后可能会同时出现这些方面的总结内容。

751
来自专栏Web 开发

iOS9.1终于可以关闭讨厌的300ms延迟了

https://developer.apple.com/library/prerelease/mac/releasenotes/General/WhatsNew...

800
来自专栏林德熙的博客

win10 UWP 用Path画图

内容是看到 大神写的 WPF绘制简单常用的Path,想到 UWP 画图是不是也一样,于是做的一个抄袭的 Path

1621
来自专栏逸鹏说道

06.移动先行之谁主沉浮----我的代码我来写(Xaml的优势)

如果移动方向有任何问题请参考===> 异常处理汇总-移动系列(点) 前面几节课,我们都是在前台创建对象,进行一些设置,那么我们为什么不用传统的方法来编程呢? 我...

2645
来自专栏xx_Cc的学习总结专栏

六天完成一个简单iOS App - 第六天

2985
来自专栏DeveWork

自定义(修改)WordPress管理后台界面的字体样式

默认的话,WordPress 后台管理界面的字体样式是“sans-serif”,中文的话直接是宋体了(当然,在Windows的机子上是这样,苹果机可能不同)。不...

2927
来自专栏林德熙的博客

win10 uwp win2d CanvasVirtualControl CanvasAnimatedControlCanvasVirtualControl其他博客

本文来告诉大家 CanvasVirtualControl ,在什么时候使用这个控件。

1531
来自专栏Bug生活2048

.net core下对于Excel的一些操作及使用

对于后台相关的管理系统,Excel导出是基本的功能,下面就简单说下实现该功能的代码实现吧

1412
来自专栏张善友的专栏

[翻译]开发Silverlight 2.0的自定义控件

原文:Developing a Custom Control for Silverlight 2.0 译者:张善友 Download MediaButto...

2179
来自专栏个人随笔

初识Windows程序

window 操作系统中,处处是窗体 简单 强大 方便 灵活 步骤 新建项目  项目类型 visual C#项目 模板 window应用程序 用partial ...

2134

扫码关注云+社区