从字节数组创建一个BitmapImage

6
我正在创建一个包含任意值的字节数组,并希望将其转换为BitmapImage。
    bi = new BitmapImage();
    using (MemoryStream stream = new MemoryStream(data))
    {
      try
      {
        bi.BeginInit();
        bi.CacheOption = BitmapCacheOption.OnLoad;
        bi.StreamSource = stream;
        bi.DecodePixelWidth = width;

        bi.EndInit();

      }
      catch (Exception ex)
      {
        return null;
      }
    }

这段代码经常会出现NotSupportedException异常。我该如何从任意字节数组中创建BitmapSource?

也许你想要做这件事:如何将byte[]转换为BitmapImage(今天问的)。如果是这样,那么这个问题很可能会被关闭为重复。 - Clemens
2个回答

9

给定一个字节数组,其中每个字节代表一个像素值,您可以创建一个灰度位图,如下所示。您需要指定位图的宽度和高度,当然必须与缓冲区大小匹配。

byte[] buffer = ... // must be at least 10000 bytes long in this example

var width = 100; // for example
var height = 100; // for example
var dpiX = 96d;
var dpiY = 96d;
var pixelFormat = PixelFormats.Gray8; // grayscale bitmap
var bytesPerPixel = (pixelFormat.BitsPerPixel + 7) / 8; // == 1 in this example
var stride = bytesPerPixel * width; // == width in this example

var bitmap = BitmapSource.Create(width, height, dpiX, dpiY,
                                 pixelFormat, null, buffer, stride);

每个字节值也可以代表一个颜色调色板的索引,这种情况下您需要指定PixelFormats.Indexed8,并且还要传递合适的颜色调色板。


1
我认为你的意思是进行除法运算,而不是乘以8。var bytesPerPixel = (pixelFormat.BitsPerPixel + 7) / 8; // 在本例中等于1 - Sami Kuhmonen
我在这里用你的代码详细说明了一个问题。如果您能够指出我的故障所在,我将很乐意删除所有这些评论。链接 - wilsotc
1
我发现只需传递零给 dpiXdpiY 更容易。生成的位图将恰好有 width x height 个像素。传递 96 似乎完全可以,但我不确定这是否是保证行为或者它是否会改变,例如取决于一些系统设置。 - Paul Groke

1
字节数组必须包含有效的图像数据(PNG / JPG / BMP)。 如果您移除了使用块并且数据有效,则您的代码应该可以工作。BitmapImage似乎不能立即加载图像,因此在流已被丢弃后无法加载它。 “任意值”是什么意思?随机的RGB值吗?那么我建议使用 Bitmap类,并将结果Bitmap保存在MemoryStream中。
如果您只想将Byte []绑定到用户界面中的Image Control:请直接绑定数组。它可以在没有转换器的情况下工作。

bi.CacheOption = BitmapCacheOption.OnLoad 会强制读取流并允许释放该流。 - Brent Stewart
在我的例子中,我指的是一个填充了0到255之间的值的字节数组。 - tabina

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接