C# gif 图像到 MemoryStream 并返回(丢失动画)

发布于 2024-12-25 02:49:28 字数 1138 浏览 2 评论 0原文

我有一个小问题,我没有找到任何解决方案。 我想将 GIF 转换为 byte[],然后再转换回 GIF。我工作得很好,但我失去了动画。

当我开始时,它是一个完美的动画 GIF(我在 PictureBox 元素中显示它)。但转换后我陷入了第一帧。

HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create("creativetechs.com/i/tip_images/ExampleAnimation.gif");
HttpWebResponse httpWebReponse = (HttpWebResponse)httpWebRequest.GetResponse();
Stream stream = httpWebReponse.GetResponseStream();
Image img = Image.FromStream(stream);

MemoryStream ms = new MemoryStream();
img.Save(ms,img.RawFormat);
byte [] bytes = ms.ToArray();
Image img2 = Image.FromStream(new MemoryStream(bytes));

int frames1 = img.GetFrameCount(System.Drawing.Imaging.FrameDimension.Time);
int frames2 = img2.GetFrameCount(System.Drawing.Imaging.FrameDimension.Time);

我还尝试不使用 RawFormat 而是使用 System.Drawing.Imaging.ImageFormat.Gif 。没有改变任何事情。 frames1 是正确的帧数。 frames2 是 1。

我的 GUI 中有 2 个 PictureBox 元素。一个显示 img,另一个显示 img2。但 img2 没有动画,而 img 则有动画。怎么了?

我还尝试使用序列化来创建我的 byte[]。

我序列化了图像并再次反序列化它,它也没有改变任何东西。这怎么可能?

I have a small problem and I do not find any solutions.
I want to convert a GIF to a byte[] and then back to a GIF. I works fine but I lose the animation.

It is a perfectly animated GIF when I start (I show it in a PictureBox element). But after conversion I get stuck with the first frame.

HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create("creativetechs.com/i/tip_images/ExampleAnimation.gif");
HttpWebResponse httpWebReponse = (HttpWebResponse)httpWebRequest.GetResponse();
Stream stream = httpWebReponse.GetResponseStream();
Image img = Image.FromStream(stream);

MemoryStream ms = new MemoryStream();
img.Save(ms,img.RawFormat);
byte [] bytes = ms.ToArray();
Image img2 = Image.FromStream(new MemoryStream(bytes));

int frames1 = img.GetFrameCount(System.Drawing.Imaging.FrameDimension.Time);
int frames2 = img2.GetFrameCount(System.Drawing.Imaging.FrameDimension.Time);

I also tried to use not RawFormat but System.Drawing.Imaging.ImageFormat.Gif. Didn't change a thing. frames1 is right number of frames. frames2 is 1.

I have 2 PictureBox elements in my GUI. One showing img and the other img2. But img2 is not animated while img is. What is wrong?

I have also tried to use serialization instead to create my byte[].

I serialized the image and deserialized it again and it didn't change anything either. How is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

平安喜乐 2025-01-01 02:49:28

当您从 Stream 加载图像时,.NET 框架会检测到 GIF 是动画的。由于它知道无法重新编码动画 GIF,因此它会尝试存储 GIF 的原始编码。但这是在读取流并解码 GIF 之后发生的。因此,当它尝试倒带流时,会失败并且最终不会存储原始流。

当您调用 Save() 时,它首先检查是否存储了原始编码。但由于该操作失败,它会尝试重新编码 GIF。由于 .NET 没有用于动画 GIF 的编码器,因此它仅对第一帧进行编码。

如果您使用 FileStream ,它就可以工作,因为 FileStream 是可查找的。

您可以通过首先将响应加载到 MemoryStream 来使代码正常工作:

// ...
Stream stream = httpWebReponse.GetResponseStream();

MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
memoryStream.Position = 0;
stream = memoryStream;

Image img = Image.FromStream(stream);
// ...

如果您想查看发生的情况,请启用 .NET 参考源调试并注意 Image.EnsureSave() 中发生的情况。您还会注意到,Image 实现已经将 Stream 复制到 MemoryStream 中,以便他们可以通过使用它而不是原始 Stream 来解决问题。

When you load your image from a Stream, the .NET framework detects that the GIF is animated. Since it knows that it will be unable to reencode an animated GIF, it tries to store the original encoding of the GIF. But this happens after it has read the stream and decoded the GIF. So when it tries to rewind the stream this fails and it ends up not storing the original.

When you call Save() it first checks whether it has the original encoding stored. But since that operation failed, it attempts to reencode the GIF. Since .NET does not have an encoder for animated GIFs, it only encodes the first frame.

If you use a FileStream instead it works, since a FileStream is seekable.

You can make your code work by loading the response into a MemoryStream first:

// ...
Stream stream = httpWebReponse.GetResponseStream();

MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
memoryStream.Position = 0;
stream = memoryStream;

Image img = Image.FromStream(stream);
// ...

If you want to see what happens, enable .NET reference source debugging and note what happens in Image.EnsureSave(). You will also note that the Image-implementation already copies the Stream into a MemoryStream, so that they could fix the problem by using that instead of the original Stream.

微暖i 2025-01-01 02:49:28

GDI+ 不包含任何动画 GIF 编码器(只是一个解码器)。所以你的img.Save将会删除动画。但你可以尝试这个: http://www.codeproject.com/KB/GDI -plus/NGif.aspx

GDI+ does not contain any animated GIF encoder (just a decoder). So your img.Save will drop the animation. But you could try this: http://www.codeproject.com/KB/GDI-plus/NGif.aspx

岁吢 2025-01-01 02:49:28

正如“Rasmus Faber”于 2012 年 1 月 17 日 20:00 引用的 ==>我根据他的建议开发了图像滑块程序,效果非常好。多谢。
我的示例代码如下。能够毫无错误地加载 LPG 和动画 GIF,还能够删除所有不需要的文件。

Dim t1 As String
t1 = ListBox5.SelectedItem.ToString
Dim mmp As MemoryStream
mmp = New MemoryStream()

Using str As Stream = File.OpenRead(t1)
str.CopyTo(mmp)
End Using
PictureBox8.Image = Image.FromStream(mmp)

As "Rasmus Faber" quoted on Jan 17 '12 at 20:00 ==> I was developed my image slider prog as his advise and it works so good. Thanks a lot.
My sample code are as below. Enable to load both of LPG and animation GIF by without any error and also enable to delete all un-need file.

Dim t1 As String
t1 = ListBox5.SelectedItem.ToString
Dim mmp As MemoryStream
mmp = New MemoryStream()

Using str As Stream = File.OpenRead(t1)
str.CopyTo(mmp)
End Using
PictureBox8.Image = Image.FromStream(mmp)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文