Creación de mapimentación de bits WPF desde MemoryStream PNG, GIF
-
21-09-2019 - |
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?
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;