为什么 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,提示“值不在预期范围内”。这不是这样做的方法吗?我是不是没有正确拨打电话?
I'm trying to get an bitmap created from raw data to show in WPF, by using an Image and a 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;
However the call to BitmapSource.Create throws an ArgumentException, saying "Value does not fall within the expected range". Is this not the way to do this? Am I not making that call properly?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你的步幅不正确。 Stride 是为一个扫描线分配的字节数
位图。因此,请使用以下内容:
并将最后一个参数(当前为
0
)替换为上面定义的stride
。以下是对神秘步幅公式的解释:
事实:扫描线必须在 32 位边界上对齐 (参考)。
每个扫描线的字节数的简单公式是:
但这可能不会给我们一个在 32 位边界上对齐的位图,并且 (width * bpp) 甚至可能无法被 8 整除。
所以,我们要做的是强制我们的位图连续至少有 32 位(我们假设
width > 0
):然后我们说我们不关心低位(位 0-- 4) 因为我们试图在 32 位边界上对齐:
然后除以 8 返回字节数:
填充可以通过以下方式计算:
简单的公式是
但是
width * bpp
可能不会对齐在字节边界上,如果不在字节边界上,则此公式将超额计算一个字节的填充。 (想象一下使用 1 bpp 的 1 像素宽位图。步幅为 4,天真的公式会说填充为 4,但实际上它是 3。)因此,我们添加一点点来覆盖width 的情况* bpp
不是字节边界,然后我们得到上面给出的正确公式。Your stride is incorrect. Stride is the number of bytes allocated for one scanline of the
bitmap. Thus, use the following:
and replace the last parameter (currently
0
) withstride
as defined above.Here is an explanation for the mysterious stride formula:
Fact: Scanlines must be aligned on 32-bit boundaries (reference).
The naive formula for the number of bytes per scanline would be:
But this might not give us a bitmap aligned on a 32-bit boundary and (width * bpp) might not even have been divisible by 8.
So, what we do is we force our bitmap to have at least 32 bits in a row (we assume that
width > 0
):and then we say that we don't care about the low-order bits (bits 0--4) because we are trying to align on 32-bit boundaries:
and then divide by 8 to get back to bytes:
The padding can be computed by
The naive formula would be
But
width * bpp
might not align on a byte boundary and when it doesn't this formula would over count the padding by a byte. (Think of a 1 pixel wide bitmap using 1 bpp. The stride is 4 and the naive formula would say that the padding is 4 but in reality it is 3.) So we add a little bit to cover the case thatwidth * bpp
is not a byte boundary and then we get the correct formula given above.