Criando o BitmapImage do WPF a partir do MemoryStream png, gif

Estou tendo problemas para criar um BitmapImage partir de um MemoryStream de png e gif bytes obtidos de uma solicitação da web. Os bytes parecem ser baixados bem e o object BitmapImage é criado sem problemas, mas a imagem não está renderizando na minha interface do usuário. O problema só ocorre quando a imagem baixada é do tipo png ou gif (funciona bem para jpeg).

Aqui está o código que demonstra o 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 testar se a solicitação da Web estava obtendo corretamente os bytes, tentei o seguinte, que salva os bytes em um arquivo no disco e, em seguida, carrega a imagem usando um UriSource vez de um StreamSource e funciona para todos os tipos de imagem:

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

Alguém tem alguma luz para brilhar?

Adicione bi.CacheOption = BitmapCacheOption.OnLoad diretamente após o seu .BeginInit() :

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

Sem isso, BitmapImage usa boot lenta por padrão e stream será fechado até então. No primeiro exemplo, você tenta ler a imagem de MemoryStream possivelmente fechado ou mesmo descartado. O segundo exemplo usa o arquivo, que ainda está disponível. Além disso, não escreva

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

Melhor

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

Eu estou 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; } 

Pode ser que você deve excluir esta linha:

 bi.DecodePixelWidth = 30;