【问题标题】:stride and padding of an image图像的步幅和填充
【发布时间】:2015-04-28 06:53:43
【问题描述】:

我想使用CreateBitmapFromMemory 方法,它需要步幅作为输入。而这一步让我很困惑。

cbStride [in]

类型:UINT

pbBuffer 中连续扫描线之间的字节数。

here 它说:步幅 = 图像宽度 + 填充

  1. 为什么我们需要这些额外的空间(填充)。为什么不只是图像宽度。

这是如何计算步幅的吧?

    lWidthByte = (lWidth * bits + 7) / 8;

lWidth→像素数

位→每像素位数

我认为除以 8 是为了转换为字节。但是,

  1. (+7) 在这里做什么?

最后

    cbStride =((lWidthByte + 3) / 4) * 4;
  1. 这是怎么回事? (为什么不 cbStride = lWidthByte)

请帮我清除这些。

【问题讨论】:

    标签: image image-processing


    【解决方案1】:

    填充的使用是由于各种(旧的和当前的)内存布局优化。
    图像像素行的长度(以字节为单位)是 4/8/16 字节的整数倍,可以显着简化和优化许多基于图像的操作。原因是这些大小允许在 CPU 寄存器中正确存储和并行像素处理,例如使用 SSE/MMX,无需混合来自两个连续行的像素。
    如果没有填充,则必须插入额外的代码来处理部分 WORD/DWORD 像素数据,因为内存中的两个连续像素可能引用一行右侧的一个像素和下一行的左侧像素。

    如果您的图像是具有 8 位深度的单通道图像,即 [0,255] 范围内的灰度,那么步幅将是图像宽度向上取整到最接近的 4 或 8 字节的倍数。请注意,即使像素的深度可能超过一个字节,步幅也始终以字节为单位。

    对于具有更多通道和/或每个像素/通道超过一个字节的图像,步幅将是图像宽度以字节为单位四舍五入到最接近的 4 或 8 个字节的倍数。 p>

    +7 和您提供的类似算术示例只是确保数字正确舍入,因为整数数学会截断除法的非整数部分。
    只需插入一些数字,看看它是如何工作的。不要忘记截断 (floor()) 中间除法结果。

    【讨论】:

    • 谢谢@Adi。我也试过没有填充。 (cbStride = lWidthByte x heght) 程序看起来不错。如果我计算为 4 字节的汇总边界会加速应用程序吗?
    • 可能会稍微快一些。然而,速度不再是真正的主要问题。这实际上取决于图像的使用。如果您将它与需要 4 字节图像行的 API 一起使用,那么没有它的图像可能会损坏或错误处理。
    • 我使用了 WIC 并尝试了 4 字节图像行和没有填充。两者看起来都不错(用 2 或 3 张图像测试)。在这种情况下,哪种方法是最好的计算方法?为什么?
    • 在分配位图时是否实际使用填充实际上取决于您计划使用位图的 API。许多 API 在没有填充的情况下工作没有问题,因此您不应该看到任何问题。您的问题仅询问填充是什么以及如何计算它。
    • 将步幅与宽度分开还可以让您在不复制的情况下使用大图像的子集。 stride=存储布局,宽度=实际查看的列数。
    猜你喜欢
    • 1970-01-01
    • 2016-03-10
    • 2019-04-23
    • 2018-05-05
    • 2013-03-27
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多