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