2012-01-06 54 views
13

Tengo un pequeño problema y no encuentro ninguna solución. Quiero convertir un GIF en un byte [] y luego volver a un GIF. Yo trabajo bien pero pierdo la animación.C# gif Imagen en MemoryStream y volver (perder animación)

Es un GIF perfectamente animado cuando comienzo (lo muestro en un elemento PictureBox). Pero después de la conversión me quedo atascado con el primer fotograma.

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); 

También probé a utilizar no RawFormat pero System.Drawing.Imaging.ImageFormat.Gif. No cambió nada. frames1 es el número correcto de marcos. frames2 es 1.

Tengo 2 PictureBox elementos en mi GUI. Una mostrando img y la otra img2. Pero img2 no está animado, mientras que img es. ¿Qué está mal?

También intenté usar la serialización para crear mi byte [].

serialicé la imagen y la deserialicé de nuevo y tampoco cambió nada. ¿Cómo es esto posible?

+3

El codificador gdi GDI + no es compatible con SaveAdd() ni gifs animados. –

+0

¿Ha considerado que puede ser un problema con el GIF? Acabo de probar tu código exacto con este [GIF] (http://www.creativetechs.com/iq/tip_images/ExampleAnimation.gif) y no funcionó. Ambos 'frames1' y' frames2' equivalen a 17. –

+0

¿Y por qué puedo cargar y visualizar un gif animado desde un Web ResponseStream? –

Respuesta

9

Cuando carga su imagen desde un Stream, el .NET framework detecta que el GIF está animado. Como sabe que no podrá volver a codificar un GIF animado, intentará almacenar la codificación original del GIF. Pero esto sucede después de que ha leído la secuencia y decodificado el GIF. Por lo tanto, cuando intenta rebobinar la transmisión, falla y termina no almacenando el original.

Cuando llame al Save() primero comprueba si tiene la codificación original almacenada. Pero dado que esa operación falló, intenta volver a codificar el GIF. Como .NET no tiene un codificador para GIF animados, solo codifica el primer fotograma.

Si utiliza un FileStream en su lugar funciona, ya que un FileStream es buscable.

Usted puede hacer su trabajo de código mediante la carga de la respuesta en una primera MemoryStream:

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

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

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

Si quieres ver lo que sucede, permitirá .NET referencia depuración fuente y observar lo que ocurre en Image.EnsureSave() . También notará que la implementación de imagen ya copia el flujo en un MemoryStream, para que puedan solucionar el problema al usarlo en lugar del flujo original.

+0

wow :). finalmente una muy buena respuesta. muchas gracias. –

+0

Rasmus: ¿Su solución no sufrirá este problema? http://support.microsoft.com/kb/814675 "Además, si la secuencia se destruyó durante la vigencia del objeto Bitmap, no se puede acceder correctamente a una imagen que se basó en una secuencia". El objeto Bitmap no mantiene una referencia a la secuencia. Si la transmisión está dispuesta, las referencias al mapa de bits fallarán. Se saldrá con la suya cuando trabaje con mapas de bits regulares, pero si crea un GIF animado a partir de un flujo, volver a dibujar el GIF animado fallará en algunos sistemas. – MindModel

2

GDI + no contiene ninguna de animación GIF codificador (sólo un decodificador ). Entonces su img.Save soltará la animación. Pero puede intentar esto: http://www.codeproject.com/KB/GDI-plus/NGif.aspx

+0

Funciona perfectamente si carga el archivo .gif desde un archivo, pero no si lo carga desde una respuesta http. –

Cuestiones relacionadas