c++ - 非双字对齐像素到双字对齐位图

标签 c++ visual-c++ dword

我必须将不是 DWORD 对齐的原始像素数据 (rows *col = 479 * 638) 转换为 DWORD 对齐位图数据。我几乎没有怀疑。

1) 当我说 d 字对齐时,它是关于分配双字对齐的总内存还是关于使宽度 DWORD 对齐?

2) 如果它是关于使实际宽度为 DWORD 对齐,那么由于 DWORD 对齐,我在末尾添加了额外的 2 个字节以使宽度 = 640。但是当我从源到目标进行 memcopy 时,它离开底部有一条深黑色的线。但我不想要这些暗线,因为它会造成与实际图像的混淆。那么如何避免最后出现这条黑线呢?

为了解决这个问题,我假设这是关于分配的总内存,它是双字对齐的。我分配了那么多双字对齐的内存。

bitmapData = (LPBYTE) GlobalAlloc(GMEM_FIXED, bmiHeader->biSizeImage);

其中 bmiHeader->biSizeImage = nrows * dowrdalignedwidth * BPP。

在执行实际的 memcopy 时,我正在复制并写入 rows*cols*BPP。这是正确的吗?

最佳答案

图像的 DWORD 对齐通常用于步幅,即宽度,并且以字节而不是像素为单位。 现在您正在更改像素数,您必须将其设置为 4 的倍数,但这将使每行的总字节数增加很多,实际上可能增加 8 个字节。

您所做的是计算(列数 * 每像素位数),然后将其与 32 位对齐以获得您的步幅或宽度。 然后您可以将其乘以高度以获得完整的图像大小。

因此对于 479 * 638 的图像,638 是列,因此是宽度。
如果你的图像是每像素 4 字节,那么你不需要做任何特殊的事情,因为 DWORD 是 4 字节,所以你的字节总宽度是 4 字节或 32 位的倍数,638 * 4 = 2552。所以只需乘以它按高度得到您的总图像大小(以字节为单位)。

但是,如果您的图像是每个像素 3 个字节,则 638 * 3 = 1914 并且 1914 不是 4 的偶数倍。 因此,您需要将 1914 个字节填充到下一个 4 的倍数。

我通常在 C# 中这样做,所以我使用的公式是:

((宽度 & 每像素位数) + 31) & ~31

如果需要,然后将结果除以 8 以字节而不是位的形式得到它。

所以在您的情况下,如果您执行 (638 * 24)/8 以获得 1914 个字节,这不是 DWORD 对齐值,但是使用上面的公式您将得到 1916,它是 4 个字节的偶数倍并且是正确的值为了你的步伐。

关于c++ - 非双字对齐像素到双字对齐位图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14686694/

相关文章:

c++ - 如何有效地找到数组中三元组和的最小差异?

c++ - 位字段和值初始化导致缓冲区溢出 - 编译器错误或未定义的行为?

qt - 将 DWORD 值转换为 QString

c - 低位和高位 DWORD => size_t

C++ 在静态函数中访问私有(private)静态变量

c++ - 向不同 header 中定义的类中的函数授予友元

c++ - 行星渲染的最佳 CLOD 方法

c++ - 修复了 VSync 打开时的时间步长卡顿

c++ - 数组迭代器不可取消引用错误

c++ - 使用 DWORD 属性从 IShellFolder 获取文件/文件夹属性