C # gif Изображение в MemoryStream и обратно (потеря анимации) - PullRequest
13 голосов
/ 06 января 2012

У меня небольшая проблема, и я не нахожу никаких решений. Я хочу преобразовать GIF в байт [], а затем обратно в 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.

В моем графическом интерфейсе 2 PictureBox элемента. Один показывает img, а другой img2. Но img2 не анимируется, в то время как img. Что не так?

Я также попытался использовать сериализацию вместо того, чтобы создать свой байт [].

Я сериализовал образ и снова десериализовал его, и он тоже ничего не изменил. Как это возможно?

Ответы [ 2 ]

9 голосов
/ 18 января 2012

Когда вы загружаете свое изображение из Stream, .NET Framework обнаруживает, что 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.

2 голосов
/ 07 января 2012

GDI + не содержит анимированного кодера GIF (только декодер ).Таким образом, ваш img.Save отбросит анимацию.Но вы можете попробовать это: http://www.codeproject.com/KB/GDI-plus/NGif.aspx

...