为什么BitmapSource.Create会抛出ArgumentException?

我试图通过使用Image和BitmapSource从WPF中显示原始数据创建的位图:

Int32[] data = new Int32[RenderHeight * RenderWidth]; for (Int32 i = 0; i < RenderHeight; i++) { for (Int32 j = 0; j < RenderWidth; j++) { Int32 index = j + (i * RenderHeight); if (i + j % 2 == 0) data[index] = 0xFF0000; else data[index] = 0x00FF00; } } BitmapSource source = BitmapSource.Create(RenderWidth, RenderHeight, 96.0, 96.0, PixelFormats.Bgr32, null, data, 0); RenderImage.Source = source; 

但是,对BitmapSource.Create的调用会抛出ArgumentException,并说“值不在预期范围内”。 这不是这样做的方法吗? 我没有正确地打电话吗?

你的步伐不正确。 Stride是为位图的一条扫描线分配的字节数。 因此,请使用以下内容:

 int stride = ((RenderWidth * 32 + 31) & ~31) / 8; 

并使用上面定义的stride替换最后一个参数(当前为0 )。

以下是对神秘步伐公式的解释:

事实:扫描线必须在32位边界上对齐( 参考 )。

每条扫描线的字节数的天真公式为:

 (width * bpp) / 8 

但这可能不会给我们在32位边界上对齐的位图,并且(width * bpp)甚至可能无法被8整除。

所以,我们要做的是强制我们的位图连续至少有32位(我们假设width > 0 ):

 width * bpp + 31 

然后我们说我们不关心低位(位0–4),因为我们试图在32位边界上对齐:

 (width * bpp + 31) & ~31 

然后除以8以返回字节:

 ((width * bpp + 31) & ~31) / 8 

填充可以通过计算

 int padding = stride - (((width * bpp) + 7) / 8) 

天真的公式将是

 stride - ((width * bpp) / 8) 

但是width * bpp可能不会在字节边界上对齐,而当它没有时,这个公式会过度计算填充一个字节。 (想象一个1像素宽的位图使用1 bpp。步幅是4,天真的公式会说填充是4但实际上它是3.)所以我们添加一点来覆盖width * bpp是的情况不是字节边界,然后我们得到上面给出的正确公式。