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

时间:2013-09-10 12:43:49

标签: 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也不会循环(我希望循环元数据无论如何都需要是全局的)。

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

2 个答案:

答案 0 :(得分:3)

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

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

GifBitmapEncoder似乎编写了Header,Logical Screen Descriptor,然后是Graphics Control Extension。 " 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());
        }

答案 1 :(得分:-1)

您知道可以下载此功能吗?请查看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设置动画。)