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

C# .NET-使用GifBitmapEncoder创建循环.gif,c#,wpf,vb.net,animated-gif,C#,Wpf,Vb.net,Animated Gif,我正在尝试编写一些代码,以便使用GifBitmapEncoder从WPF应用程序导出动画.gif。到目前为止,我所做的一切都很好,但是当我查看生成的.gif文件时,它只运行一次,然后就停止了——我希望它能够无限期地循环 我发现了前面类似的问题: 但是,他使用的是Windows.Graphics.Imaging中的BitmapEncoder,而不是Windows.Media.Imaging版本,这似乎有点不同。尽管如此,这给了我一个方向,在谷歌搜索了一段时间后,我想到了这个: Dim encod

我正在尝试编写一些代码,以便使用GifBitmapEncoder从WPF应用程序导出动画.gif。到目前为止,我所做的一切都很好,但是当我查看生成的.gif文件时,它只运行一次,然后就停止了——我希望它能够无限期地循环

我发现了前面类似的问题:

但是,他使用的是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也不会循环(我希望循环元数据无论如何都需要是全局的)


有人能提供一些建议吗?

你知道你可以下载这个功能吗?查看
CodePlex
上的页面。或者,在
Nuget Gallery
上有。如果您喜欢教程,请查看
code项目
网站上的页面


@保罗·杰弗里斯,我向你道歉。。。我误解了你的问题。我以前使用过一篇文章中的一些代码来制作.gif文件的动画。这是非常直接的,您可能能够“反向工程”它为您的目的。请看一下这篇文章,看看这是否有帮助。(我知道该代码的实际用途也是为.gif制作动画)。

在研究和引用了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());
        }
//将所有帧添加到gifEncoder(GifBitmapEncoder)后。。。
使用(var ms=new MemoryStream())
{
保存(ms);
var fileBytes=ms.ToArray();
//这是NETSCAPE2.0应用程序扩展。
var applicationExtension=新字节[]{33、255、11、78、69、84、83、67、65、80、69、50、46、48、3、1、0、0};
var newBytes=新列表();
AddRange(fileBytes.Take(13));
newBytes.AddRange(applicationExtension);
AddRange(fileBytes.Skip(13));
writealBytes(saveFile,newBytes.ToArray());
}

为什么不使用Windows.Graphics.Imaging?对不起,我应该说-Windows.Graphics.Imaging似乎只能在Windows 8环境中使用,这对我没有好处。即使不是这样,我也希望避免在项目中添加任何我不需要的依赖项。根据MSDN:“图形交换格式(GIF)图像不支持全局预览、全局缩略图、全局元数据、帧级缩略图或帧级元数据。”你有没有找到一个合适的解决方案?@教授:恐怕没有,因为这是一个业余爱好项目中不重要的部分,我就顺其自然了。我的两个最佳选择似乎是要么放弃GifBitmapEncoder,滚动我自己的.gif编写器,要么使用它写出gif,然后在文件中插入适当的应用程序扩展名。我仍然有兴趣找到一个简单的方法来做,所以如果你设法找到什么,请让我知道!谢谢谢里登,不幸的是,那些页面只显示了与我试图做的相反的内容!我并不是试图在WPF应用程序中显示循环gif,而是试图从WPF应用程序中导出循环gif,以便在其他地方(例如,在web浏览器中)查看时,它会自动循环。