【问题标题】:.NET - Creating a looping .gif using GifBitmapEncoder.NET - 使用 GifBitmapEncoder 创建循环的 .gif
【发布时间】:2013-09-14 04:27:28
【问题描述】:

我正在尝试编写一些代码来使用 GifBitmapEncoder 从 WPF 应用程序中导出动画 .gif。到目前为止我的工作正常,但是当我查看生成的 .gif 时,它只运行一次然后停止 - 我想让它无限循环。

我发现了这个以前的类似问题:

How do I make a GIF repeat in loop when generating with BitmapEncoder

但是,他使用的是 Windows.Graphics.Imaging 中的 BitmapEncoder,而不是 Windows.Media.Imaging 版本,这似乎有点不同。尽管如此,这给了我一个方向,经过更多的谷歌搜索后,我想出了这个:

Dim encoder As New GifBitmapEncoder
Dim metaData As New BitmapMetadata("gif")
metaData.SetQuery("/appext/Application", System.Text.Encoding.ASCII.GetBytes("NETSCAPE2.0"))
metaData.SetQuery("/appext/Data", New Byte() {3, 1, 0, 0, 0})

'The following line throws the exception "The designated BitmapEncoder does not support global metadata.":
'encoder.Metadata = metaData

If DrawingManager.Instance.SelectedFacing IsNot Nothing Then
   For Each Frame As Frame In DrawingManager.Instance.SelectedFacing.Frames
       Dim bmpFrame As BitmapFrame = BitmapFrame.Create(Frame.CombinedImage, Nothing, metaData, Nothing)
       encoder.Frames.Add(bmpFrame)
   Next
End If

Dim fs As New FileStream(newFileName, FileMode.Create)
encoder.Save(fs)
fs.Close()

最初我尝试将元数据直接添加到编码器(如上面代码中注释掉的行),但在运行时抛出异常“指定的 BitmapEncoder 不支持全局元数据”。相反,我可以将我的元数据附加到每个帧,但是虽然这不会导致它崩溃,但生成的 .gif 也不会循环(我希望循环的元数据无论如何都需要是全局的)。

谁能给点建议?

【问题讨论】:

  • 为什么不使用 Windows.Graphics.Imaging?
  • 对不起,我应该说 - Windows.Graphics.Imaging 似乎只能在 Windows 8 环境中使用,这对我没有好处。即使不是这样,我也希望避免在项目中添加任何我不需要的依赖项。
  • 根据 MSDN:“图形交换格式 (GIF) 图像不支持全局预览、全局缩略图、全局元数据、帧级缩略图或帧级元数据。”
  • 您找到合适的解决方案了吗?
  • @Prof:恐怕不是,因为它是一个业余项目的非必要部分,我让它滑动。我的两个最佳选择似乎要么放弃 GifBitmapEncoder 并推出我自己的 .gif 编写器,要么使用它写出 gif,然后将适当的应用程序扩展名插入文件中。我仍然有兴趣找到一种简单的方法,所以如果你找到了一些东西,请告诉我!

标签: c# wpf vb.net animated-gif


【解决方案1】:

在研究了this article 并引用了 GIF 文件的原始字节后,我终于得到了这个工作。如果你想自己这样做,你可以像这样使用 PowerShell 获取十六进制格式的字节......

$bytes = [System.IO.File]::ReadAllBytes("C:\Users\Me\Desktop\SomeGif.gif")
[System.BitConverter]::ToString($bytes)

GifBitmapEncoder 似乎是编写标题、逻辑屏幕描述符,然后是图形控件扩展。缺少“NETSCAPE2.0”扩展。在 循环的其他来源的 GIF 中,缺少的扩展总是出现在图形控件扩展之前。

所以我只插入了第 13 个字节之后的字节,因为前两个部分总是这么长。

        // After adding all frames to gifEncoder (the GifBitmapEncoder)...
        using (var ms = new MemoryStream())
        {
            gifEncoder.Save(ms);
            var fileBytes = ms.ToArray();
            // This is the NETSCAPE2.0 Application Extension.
            var applicationExtension = new byte[] { 33, 255, 11, 78, 69, 84, 83, 67, 65, 80, 69, 50, 46, 48, 3, 1, 0, 0, 0 };
            var newBytes = new List<byte>();
            newBytes.AddRange(fileBytes.Take(13));
            newBytes.AddRange(applicationExtension);
            newBytes.AddRange(fileBytes.Skip(13));
            File.WriteAllBytes(saveFile, newBytes.ToArray());
        }

【讨论】:

    【解决方案2】:

    你知道你可以下载这个功能吗?查看CodePlex 上的WPF Animated GIF 页面。或者,Nuget Gallery 上有 WPF Animated GIF 1.4.4。如果您喜欢教程,请查看Code Project 网站上的GIF Animation in WPF 页面。

    @PaulJeffries,我很抱歉......我误解了你的问题。我之前使用过这里帖子中的一些代码来制作 .gif 文件的动画。这非常简单,您可能能够根据您的目的对其进行“逆向工程”。请查看How do I get an animated gif to work in WPF? 帖子,看看是否有帮助。 (我知道代码的 实际 目的也是为 .gif 制作动画)。

    【讨论】:

    • 感谢 Sheridan,但不幸的是,这些页面只显示了与我正在尝试做的相反的事情!我不是想在 WPF 应用程序中显示循环 gif,而是尝试从 WPF 应用程序导出循环 gif,以便在其他地方查看它时 - 在 Web 浏览器中,示例 - 它自动循环。
    猜你喜欢
    • 2015-06-18
    • 2015-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-14
    • 2016-01-06
    • 1970-01-01
    • 2013-03-01
    相关资源
    最近更新 更多