c# - .NET - 使用 GifBitmapEncoder 创建循环 .gif

标签 c# wpf vb.net animated-gif

我正在尝试编写一些代码以使用 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 也不会循环(而且我希望循环元数据无论如何都需要是全局的)。

有人可以提供任何建议吗?

最佳答案

学习后终于可以用了this article并引用 GIF 文件的原始字节。如果您想自己这样做,您可以像这样使用 PowerShell 获取十六进制格式的字节...

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

GifBitmapEncoder 似乎要编写 header 、逻辑屏幕描述符,然后是图形控件扩展。 “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());
        }

关于c# - .NET - 使用 GifBitmapEncoder 创建循环 .gif,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18719302/

相关文章:

wpf - 弹出窗口中有两列的组合框

.net - 在 .net 中指定一个实现 2 个接口(interface)的变量

mysql - SQL 一次查询两个表并将结果作为 JSON 对象循环

c# - HtmlAgilityPack 读取 html 时出现问题

c# - ZedGraph - 如何在不使用鼠标的情况下在 x,y 点显示光标?

c# - Caliburn 在 ComboBox 上重置 SelectedIndex

c# - Java JPanel 与 WPF XAML 中的 GridLayout 等效

c - 使用 C DLL 的 VB.Net

c# - 如何 stub 静态方法?

c# - AJAXToolkit动态隐藏选项卡?