Создание WPF BitmapImage из MemoryStream png, gif - PullRequest
27 голосов
/ 20 января 2010

У меня возникли проблемы с созданием BitmapImage из MemoryStream из байтов png и gif, полученных из веб-запроса.Кажется, что байты загружаются нормально, и объект BitmapImage создается без проблем, однако изображение фактически не отображается в моем пользовательском интерфейсе.Проблема возникает, только когда загруженный образ имеет тип png или gif (отлично работает для jpeg).

Вот код, который демонстрирует проблему:

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

Чтобы проверить, что веб-запросправильно получал байты, я попробовал следующее, которое сохраняет байты в файл на диске, а затем загружает изображение, используя UriSource вместо StreamSource, и это работает для всех типов изображений:

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

У кого-нибудь есть свет, чтобы сиять?

Ответы [ 2 ]

48 голосов
/ 12 февраля 2010

Добавить bi.CacheOption = BitmapCacheOption.OnLoad сразу после вашего .BeginInit():

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

Без этого BitmapImage по умолчанию использует отложенную инициализацию, и поток к тому времени будет закрыт.В первом примере вы пытаетесь прочитать изображение из, возможно, мусора, собранного закрытого или даже удаленного MemoryStream.Второй пример использует файл, который все еще доступен.Кроме того, не пишите

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

лучше

using (MemoryStream byteStream = new MemoryStream(buffer))
{
   ...
}
11 голосов
/ 20 января 2010

Я использую этот код:

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

Может быть, вам следует удалить эту строку:

bi.DecodePixelWidth = 30;
...