为什么BitmapSource.Create会抛出ArgumentException?

时间:2009-12-31 03:19:26

标签: c# bitmapsource stride

我正在尝试使用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,说“Value不在预期范围内”。这不是这样做的方法吗?我没有正确地打电话吗?

1 个答案:

答案 0 :(得分:38)

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

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

并将上一个参数(目前0)替换为上面定义的stride

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

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

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

(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 bpp的1像素宽位图。步幅是4,天真的公式会说填充是4但实际上是3。)所以我们添加一点来涵盖{{1}的情况}不是字节边界,然后我们得到上面给出的正确公式。