web-dev-qa-db-fra.com

Création de WPF BitmapImage à partir de MemoryStream png, gif

J'ai du mal à créer un BitmapImage à partir d'un MemoryStream à partir d'octets png et gif obtenus à partir d'une demande Web. Les octets semblent être téléchargés correctement et l'objet BitmapImage est créé sans problème, mais l'image ne s'affiche pas réellement sur mon interface utilisateur. Le problème se produit uniquement lorsque l'image téléchargée est de type png ou gif (fonctionne correctement pour jpeg).

Voici du code qui illustre le problème:

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

Pour tester que la requête Web obtenait correctement les octets, j'ai essayé ce qui suit qui enregistre les octets dans un fichier sur le disque, puis charge l'image en utilisant un UriSource plutôt qu'un StreamSource et cela fonctionne pour tous les types d'images:

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

Quelqu'un a de la lumière pour briller?

29
Simon Fox

Ajoutez bi.CacheOption = BitmapCacheOption.OnLoad Directement après votre .BeginInit():

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

Sans cela, BitmapImage utilise l'initialisation paresseuse par défaut et le flux sera fermé d'ici là. Dans le premier exemple, vous essayez de lire l'image de ramassé MemoryStream fermé ou même éliminé. Le deuxième exemple utilise un fichier, qui est toujours disponible. N'écrivez pas non plus

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

mieux

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

J'utilise ce code:

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

Peut-être que vous devriez supprimer cette ligne:

bi.DecodePixelWidth = 30;
11
Alexander Logger