2010-01-19 23 views
22

Tengo algunos problemas para crear un BitmapImage desde un MemoryStream desde png y gif bytes obtenidos de una solicitud web. Parece que los bytes se descargaron correctamente y el objeto BitmapImage se creó sin problema, sin embargo, la imagen no se está procesando en mi interfaz de usuario. El problema solo ocurre cuando la imagen descargada es de tipo png o gif (funciona bien para jpeg).Creando WPF BitmapImage desde MemoryStream png, gif

Aquí es código que muestra el problema:

var webResponse = webRequest.GetResponse(); 
var stream = webResponse.GetResponseStream(); 
if (stream.CanRead) 
{ 
    Byte[] buffer = new Byte[webResponse.ContentLength]; 
    stream.Read(buffer, 0, buffer.Length); 

    var byteStream = new System.IO.MemoryStream(buffer); 

    BitmapImage bi = new BitmapImage(); 
    bi.BeginInit(); 
    bi.DecodePixelWidth = 30; 
    bi.StreamSource = byteStream; 
    bi.EndInit(); 

    byteStream.Close(); 
    stream.Close(); 

    return bi; 
} 

Para probar que la solicitud web fue la obtención correctamente los bytes He intentado lo siguiente que ahorra los bytes de un archivo en el disco y luego carga la imagen utilizando una UriSource en lugar de un StreamSource y funciona para todos los tipos de imágenes:

var webResponse = webRequest.GetResponse(); 
var stream = webResponse.GetResponseStream(); 
if (stream.CanRead) 
{ 
    Byte[] buffer = new Byte[webResponse.ContentLength]; 
    stream.Read(buffer, 0, buffer.Length); 

    string fName = "c:\\" + ((Uri)value).Segments.Last(); 
    System.IO.File.WriteAllBytes(fName, buffer); 

    BitmapImage bi = new BitmapImage(); 
    bi.BeginInit(); 
    bi.DecodePixelWidth = 30; 
    bi.UriSource = new Uri(fName); 
    bi.EndInit(); 

    stream.Close(); 

    return bi; 
} 

Alguien tiene ninguna luz brille?

Respuesta

43

Añadir bi.CacheOption = BitmapCacheOption.OnLoad directamente después de su .BeginInit():

BitmapImage bi = new BitmapImage(); 
bi.BeginInit(); 
bi.CacheOption = BitmapCacheOption.OnLoad; 
... 

Sin esto, BitmapImage utiliza la inicialización lenta de manera predeterminada y la transmisión se cerrará para entonces. En el primer ejemplo, intenta leer la imagen de posiblemente recogido de basura cerrado o incluso desechado MemoryStream. El segundo ejemplo usa el archivo, que todavía está disponible. Además, no se escriben

var byteStream = new System.IO.MemoryStream(buffer); 

mejor

using (MemoryStream byteStream = new MemoryStream(buffer)) 
{ 
    ... 
} 
+6

El truco 'BitmapCacheOption.OnLoad' es importante. Me gustaría agregar que debe estar entre 'BeginInit()' y 'EndInit()'. –

+0

@ PieterMüller: pista muy útil; Además, la secuencia todavía * debe * estar abierta cuando se llama a 'EndInit()' como otra restricción con la que puede tropezar. –

10

Estoy usando este código:

public static BitmapImage GetBitmapImage(byte[] imageBytes) 
{ 
    var bitmapImage = new BitmapImage(); 
    bitmapImage.BeginInit(); 
    bitmapImage.StreamSource = new MemoryStream(imageBytes); 
    bitmapImage.EndInit(); 
    return bitmapImage; 
} 

Puede ser que usted debe eliminar esta línea:

bi.DecodePixelWidth = 30; 
+1

Pero ¿qué pasa con el cierre de la secuencia de memoria que ha creado por: nuevos MemoryStream (imageBytes) creo que cambie la CacheOption es mejor, si tales como las corrientes cerradas? –

Cuestiones relacionadas