C# 为什么BitmapSource.Create会引发ArgumentException?

C# 为什么BitmapSource.Create会引发ArgumentException?,c#,bitmapsource,stride,C#,Bitmapsource,Stride,我正在尝试使用图像和位图源,从原始数据创建位图,以在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 +

我正在尝试使用图像和位图源,从原始数据创建位图,以在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;
Int32[]data=new Int32[renderhight*RenderWidth];
对于(Int32 i=0;i

但是,对BitmapSource.Create的调用引发ArgumentException,表示“值不在预期范围内”。这不是这样做的吗?我打那个电话不正确吗?

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

int stride = ((RenderWidth * 32 + 31) & ~31) / 8;
并将最后一个参数(当前为
0
)替换为上文定义的
stride

下面是对神秘步幅公式的解释:

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

每个扫描线的字节数的简单公式是:

(width * bpp) / 8
但这可能不会给我们一个在32位边界上对齐的位图,而且(宽度*bpp)可能甚至不能被8整除

因此,我们要做的是强制位图在一行中至少有32位(我们假设
width>0
):

然后我们说我们不关心低阶位(位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
不是字节边界的情况,然后我们得到上面给出的正确公式。

谢谢,但是你到底是怎么想到这个表达的呢?为什么它不是简单的渲染宽度*4?这不是一行的字节数吗?对不起,我应该提供详细信息。在您的例子中,您有
bpp=32
,因此是的,公式减少到
RenderWidth*4
。但也有一些奇怪的情况(廉价LCD使用18bpp)和扫描线必须在32位边界上对齐的事实。我提供了一般公式,并解释了如何得出上面的公式。希望这是澄清,谢谢。还有一个问题。瓷砖对这样的整数有什么作用?@Mike Pateras:这是按位not运算符。这意味着它翻转整数二进制表示中的位(因此
0
变为
1
1
变为
0
)。我说过我们要忽略
width*bpp+31
的最低五位(并隐式保留其余的)。一个简单的方法是在这五个位中生成一个
0
,在其余位中生成一个
1
;这称为位掩码。如果我们用这个位掩码(
~31
)取逻辑and和
宽度*bpp+31
,我们就屏蔽掉了我们不关心的五个低阶位。如果不清楚,请告诉我。我花了一整天的时间来处理这个问题,你的帖子帮助我在30秒内修复了代码。非常感谢你!!!如果有人需要知道,
((宽度*24+23)和~23)/8
PixelFormats.Rgb24配合使用
stride - ((width * bpp) / 8)