从 MemoryStream png、gif 创建 WPF 位图图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2097152/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:25:57  来源:igfitidea点击:

Creating WPF BitmapImage from MemoryStream png, gif

wpfimagewebrequestmemorystreambitmapimage

提问by Simon Fox

I am having some trouble creating a BitmapImagefrom a MemoryStreamfrom png and gif bytes obtained from a web request. The bytes seem to be downloaded fine and the BitmapImageobject 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).

我有一些麻烦,创建一个BitmapImageMemoryStream从png格式和GIF字节来自Web请求获得。字节似乎下载得很好,并且BitmapImage创建的对象没有问题,但是图像实际上并未在我的 UI 上呈现。仅当下载的图像类型为 png 或 gif(适用于 jpeg)时才会出现问题。

Here is code that demonstrates the problem:

这是演示问题的代码:

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

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 UriSourcerather than a StreamSourceand it works for all image types:

为了测试 Web 请求是否正确获取了字节,我尝试了以下操作,将字节保存到磁盘上的文件,然后使用 aUriSource而不是 a加载图像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;
}

Anyone got any light to shine?

有没有人可以发光?

回答by alxx

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

bi.CacheOption = BitmapCacheOption.OnLoad直接在您的后面添加.BeginInit()

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

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-collectedclosed or even disposed MemoryStream. Second example uses file, which is still available. Also, don't write

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

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

better

更好的

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

回答by Alexander Logger

I'm using this code:

我正在使用此代码:

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

May be you should delete this line:

也许你应该删除这一行:

bi.DecodePixelWidth = 30;