为什么BitmapSource.Create引发ArgumentException?
-
22-09-2019 - |
题
我想从原始数据创建的位图中WPF显示,通过使用图像和的BitmapSource:
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,称“值没有预期的范围内”。这是不是要做到这一点的呢?我不能作出这一呼吁是否正确?
解决方案
您步幅不正确。步幅分配的一个扫描线的字节数 位图。因此,使用下面的:
int stride = ((RenderWidth * 32 + 31) & ~31) / 8;
和取代如上定义的0
的最后一个参数(目前stride
)。
下面是神秘步幅公式的说明:
事实:必须Scanlines的在32位边界对齐(参考)
对于每个扫描线的字节数的幼稚公式将是:
(width * bpp) / 8
但是,这可能不是由8给我们一个32位边界上,并对准一个位图(宽×BPP)可能甚至已经整除。
所以,我们做的是我们强迫我们的位图有一排至少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
不是字节边界,然后我们得到上面给出的式正确
不隶属于 StackOverflow