2

我有个问题。我想转换BitmapImagebyte[]数组并返回。

我写了这些方法:

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……为什么?如何更正第二种方法的代码?

4

1 回答 1

5

ToByteArray你的方法有两个问题。

首先它调用BeginInitEndInit一个已经初始化的 BitmapImage 实例。这是不允许的,请参阅BeginInit中的例外列表。

其次,无法在从 Uri 而不是 Stream 创建的 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];
    }
}
于 2013-01-13T10:18:23.793 回答