.NET-使用GifBitmapEncoder创建循环的.gif [英] .NET - Creating a looping .gif using GifBitmapEncoder

查看:386
本文介绍了.NET-使用GifBitmapEncoder创建循环的.gif的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to write some code to export animated .gifs from a WPF application using GifBitmapEncoder. What I have so far works fine but when I view the resulting .gif it only runs once and then stops - I'd like to have it looping indefinitely.

我找到了之前的类似问题:

I've found this previous similar question:

我如何使用BitmapEncoder生成时,使GIF在循环中重复执行

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

However, he is using the BitmapEncoder from Windows.Graphics.Imaging rather than the Windows.Media.Imaging version, which seems to be a bit different. Nonetheless, that gave me a direction and after a bit more googling I came up with this:

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

Initially I tried adding the metadata directly to the encoder (as in the commented-out line in the code above), but at runtime that throws the exception "The designated BitmapEncoder does not support global metadata". I can instead attach my metadata to each frame, but although that doesn't crash it the resultant .gif doesn't loop either (and I would expect that the looping metadata would need to be global anyway).

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

Can anyone offer any advice?

推荐答案

在研究

I finally got this to work after studying this article and referencing the raw bytes of GIF files. If you want to do so yourself, you can get the bytes in hex format using PowerShell like so...

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

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

The GifBitmapEncoder appears to write the Header, Logical Screen Descriptor, then the Graphics Control Extension. The "NETSCAPE2.0" extension is missing. In GIFs from other sources that do loop, the missing extension always appears right before the Graphics Control Extension.

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

So I just plugged in the bytes after the 13th byte, since the first two sections are always this long.

        // 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());
        }

这篇关于.NET-使用GifBitmapEncoder创建循环的.gif的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆