byte[]到BitmapImage转换失败

本文关键字:转换 失败 BitmapImage byte | 更新日期: 2023-09-27 17:52:49

我有一个问题。我想把BitmapImage转换成byte[]数组,然后再转换回来。

我写了这些方法:

public static byte[] ToByteArray(this BitmapImage bitmapImage)
{
    byte[] bytes;
    using (MemoryStream ms = new MemoryStream())
    {
        bitmapImage.BeginInit();
        bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
        bitmapImage.StreamSource.CopyTo(ms);
        bitmapImage.EndInit();
        bytes = ms.ToArray();
    }
    return bytes;
}
public static BitmapImage ToBitmapImage(this byte[] bytes, int width, int height)
{
    BitmapImage bitmapImage = new BitmapImage();
    using (MemoryStream ms = new MemoryStream(bytes))
    {
        ms.Position = 0;
        bitmapImage.BeginInit();
        bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
        bitmapImage.StreamSource = ms;
        bitmapImage.EndInit(); // HERE'S AN EXCEPTION!!!
    }
    return bitmapImage;
}

第一个工作得很好,但是当我试图从byte[]转换成BitmapImage时,我得到了NotSupportedException…为什么?第二种方法的代码怎么改?

byte[]到BitmapImage转换失败

你的ToByteArray方法有两个问题。

首先在已经初始化的BitmapImage实例上调用BeginInitEndInit。这是不允许的,参见BeginInit中的Exceptions列表。

第二,该方法不能在从Uri而不是流创建的BitmapImage上调用。那么StreamSource属性将是null

我建议实现如下所示的方法。这个实现将适用于任何BitmapSource,而不仅仅是BitmapImages。您可以通过选择适当的BitmapEncoder来控制图像格式,例如JpegBitmapEncoder而不是PngBitmapEncoder

public static byte[] ToByteArray(this BitmapSource bitmap)
{
    var encoder = new PngBitmapEncoder(); // or any other encoder
    encoder.Frames.Add(BitmapFrame.Create(bitmap));
    using (var ms = new MemoryStream())
    {
        encoder.Save(ms);
        return ms.ToArray();
    }
}

ToByteArray方法返回的图像缓冲区总是可以通过ToBitmapImage方法转换回BitmapImage。

请注意,ToBitmapImage方法的宽度和高度参数目前未使用。


更新

解码方法的另一种实现如下所示,尽管它不返回BitmapImage,而只是基类BitmapSource的一个实例。但是,你可以将返回类型更改为BitmapFrame。

public static BitmapSource ToBitmapImage(this byte[] bytes)
{
    using (var stream = new MemoryStream(bytes))
    {
        var decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
        return decoder.Frames[0];
    }
}