C# gif 图像到 MemoryStream 并返回(丢失动画) [英] C# gif Image to MemoryStream and back (lose animation)

查看:47
本文介绍了C# gif 图像到 MemoryStream 并返回(丢失动画)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create("creativetechs.com/i/tip_images/ExampleAnimation.gif");HttpWebResponse httpWebReponse = (HttpWebResponse)httpWebRequest.GetResponse();流流 = httpWebReponse.GetResponseStream();图像 img = Image.FromStream(stream);MemoryStream ms = new MemoryStream();img.Save(ms,img.RawFormat);字节 [] 字节 = ms.ToArray();Image img2 = Image.FromStream(new MemoryStream(bytes));int frame1 = img.GetFrameCount(System.Drawing.Imaging.FrameDimension.Time);int frame2 = img2.GetFrameCount(System.Drawing.Imaging.FrameDimension.Time);

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

我的 GUI 中有 2 个 PictureBox 元素.一个显示 img 和另一个 img2.但是 img2 不是动画而 img 是.怎么了?

我也尝试过使用序列化来创建我的字节 [].

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

解决方案

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

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

如果您使用 FileStream 代替它,它会起作用,因为 FileStream 是可查找的.

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

//...流流 = httpWebReponse.GetResponseStream();MemoryStream memoryStream = new MemoryStream();stream.CopyTo(memoryStream);memoryStream.Position = 0;流 = 内存流;图像 img = Image.FromStream(stream);//...

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

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?

解决方案

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.

这篇关于C# gif 图像到 MemoryStream 并返回(丢失动画)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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