Pregunta

Tengo algunos problemas para crear un BitmapImage a partir de una MemoryStream de bytes PNG y GIF obtenidos de una solicitud web. Los bytes parecen descargarse bien y el BitmapImage El objeto se crea sin problemas, sin embargo, la imagen en realidad no está representando mi interfaz de usuario. El problema solo ocurre cuando la imagen descargada es de tipo PNG o GIF (funciona bien para JPEG).

Aquí está el código que demuestra 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 estaba obteniendo correctamente los bytes, probé lo siguiente que guarda los bytes en un archivo en el disco y luego carga la imagen utilizando un UriSource preferible a 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 luz para brillar?

¿Fue útil?

Solución

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

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

Sin esto, Bitmapimage usa inicialización perezosa de forma predeterminada y la transmisión se cerrará para entonces. En primer ejemplo, intentas leer la imagen de posiblemente recolectado MemoryStream cerrado o incluso dispuesto. El segundo ejemplo usa el archivo, que todavía está disponible. Además, no escribas

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

mejor

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

Otros consejos

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 deba eliminar esta línea:

bi.DecodePixelWidth = 30;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top