我想使用 CreateBitmapFromMemory方法,它需要步幅作为输入。而这一步让我很困惑。
cbStride [in]
Type: UINT
The number of bytes between successive scanlines in pbBuffer.
和here它说:步幅=图像宽度+填充
- 为什么我们需要这些额外的空间(填充)。为什么不只是图像宽度。
这是如何计算步幅的吧?
lWidthByte = (lWidth * bits + 7) / 8;
lWidth→像素数
位→每像素位数
我认为除以 8 是为了转换为字节。但是,
- (+7) 在这里做什么?
最后
cbStride =((lWidthByte + 3) / 4) * 4;
- 这是怎么回事? (为什么不 cbStride = lWidthByte)
请帮我清除这些。
最佳答案
填充的使用是由于各种(旧的和当前的)内存布局优化。
让图像像素行的长度(以字节为单位)是 4/8/16 字节的整数倍,可以显着简化和优化许多基于图像的操作。原因是这些大小允许在 CPU 寄存器中正确存储和并行像素处理,例如使用 SSE/MMX,无需混合来自两个连续行的像素。
如果没有填充,则必须插入额外的代码来处理部分 WORD/DWORD 像素数据,因为内存中的两个连续像素可能引用一行右侧的一个像素和下一行的左侧像素。
如果您的图像是具有 8 位深度的单 channel 图像,即 [0,255] 范围内的灰度,那么步幅将是图像宽度向上取整到最接近的 4 或 8 字节的倍数。请注意,步幅始终以字节为单位指定,即使像素可能具有多个字节深度。
对于具有更多 channel 和/或每个像素/ channel 超过一个字节的图像,步幅将是图像宽度以字节为单位四舍五入到最接近的 4 或 8 字节的倍数。 p>
您提供的 +7
和类似的算术示例只是确保数字正确四舍五入,因为整数数学会截断除法的非整数部分。
只需插入一些数字,看看它是如何工作的。不要忘记截断(floor()
)中间除法结果。
关于image - 图像的步幅和填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29912303/