34

我要将字节数组转换为System.Windows.Media.Imaging.BitmapImageBitmapImage在图像控件中显示。

当我使用第一个代码时,注意到发生了!没有错误,也没有显示图像。但是当我使用第二个时它工作正常!谁能说发生了什么事?

第一个代码在这里:

public BitmapImage ToImage(byte[] array)
{
   using (System.IO.MemoryStream ms = new System.IO.MemoryStream(array))
   {
       BitmapImage image = new BitmapImage();
       image.BeginInit();
       image.StreamSource = ms;
       image.EndInit();
       return image;
   }
}

第二个代码在这里:

public BitmapImage ToImage(byte[] array)
{
   BitmapImage image = new BitmapImage();
   image.BeginInit();
   image.StreamSource = new System.IO.MemoryStream(array);
   image.EndInit();
   return image;
 }
4

2 回答 2

68

在第一个代码示例中,流using在实际加载图像之前关闭(通过离开块)。您还必须设置BitmapCacheOptions.OnLoad以实现立即加载图像,否则流需要保持打开状态,如第二个示例所示。

public BitmapImage ToImage(byte[] array)
{
    using (var ms = new System.IO.MemoryStream(array))
    {
        var image = new BitmapImage();
        image.BeginInit();
        image.CacheOption = BitmapCacheOption.OnLoad; // here
        image.StreamSource = ms;
        image.EndInit();
        return image;
    }
}

BitmapImage.StreamSource的备注部分:

如果您希望在创建 BitmapImage 后关闭流,请将 CacheOption 属性设置为 BitmapCacheOption.OnLoad。


除此之外,您还可以使用内置类型转换将类型转换为byte[]类型ImageSource(或派生的BitmapSource):

var bitmap = (BitmapSource)new ImageSourceConverter().ConvertFrom(array);

ImageSource当您将类型的属性(例如 Image 控件的Source属性)绑定到类型为 或 的源属性string时,Uri会隐式调用 ImageSourceConverter byte[]

于 2013-01-15T11:57:29.040 回答
4

在第一种情况下,您MemoryStream在一个using块中定义了您的对象,这会导致在您离开该块时释放对象。因此,您返回BitmapImage带有处置(且不存在)的流。

MemoryStreams 不保留非托管资源,因此您可以留下内存并让 GC 处理释放过程(但这不是一个好习惯)。

于 2013-01-15T11:55:24.263 回答