从 MemoryStream png、gif 创建 WPF BitmapImage

从 MemoryStream png、gif 创建 WPF BitmapImage

问题描述:

我在从网络请求获得的 png 和 gif 字节的 MemoryStream 创建 BitmapImage 时遇到了一些麻烦.字节似乎下载得很好,BitmapImage 对象的创建没有问题,但是图像实际上并未在我的 UI 上呈现.仅当下载的图像类型为 png 或 gif(适用于 jpeg)时才会出现此问题.

I am having some trouble creating a BitmapImage from a MemoryStream from png and gif bytes obtained from a web request. The bytes seem to be downloaded fine and the BitmapImage object is created without issue however the image is not actually rendering on my UI. The problem only occurs when the downloaded image is of type png or gif (works fine for 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;
}

为了测试 Web 请求是否正确获取了字节,我尝试了以下操作,将字节保存到磁盘上的文件中,然后使用 UriSource 而不是 StreamSource 它适用于所有图像类型:

To test that the web request was correctly obtaining the bytes I tried the following which saves the bytes to a file on disk and then loads the image using a UriSource rather than a StreamSource and it works for all image types:

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

有人发光吗?

.BeginInit() 之后直接添加 bi.CacheOption = BitmapCacheOption.OnLoad:

Add bi.CacheOption = BitmapCacheOption.OnLoad directly after your .BeginInit():

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

如果没有这个,BitmapImage 默认使用延迟初始化,届时流将被关闭.在第一个示例中,您尝试从可能的 garbage-collected 关闭或什至已处理的 MemoryStream 中读取图像.第二个示例使用仍然可用的文件.还有,不要写

Without this, BitmapImage uses lazy initialization by default and stream will be closed by then. In first example you try to read image from possibly garbage-collected closed or even disposed MemoryStream. Second example uses file, which is still available. Also, don't write

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

更好

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