开始开发专门针对Windows的屏幕捕捉软件。在查看MSDN的捕捉图像示例时,我发现自己有点困惑。
请记住,当我引用位图的大小时,它不包括与实际文件相关联的头部等等。我说的是原始像素数据。我原以为公式应该是(width*height)*bits-per-pixel。但是,根据示例,这是计算大小的正确方法:
DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;或:((width*bits-per-pixel + 31) / 32) * 4 * height
我不明白为什么会有涉及31、32和4的额外计算。也许是垫子?我不确定,但是任何解释都会很感激的。我已经尝试过谷歌搜索,但没有发现任何特别有用的结果。
发布于 2018-02-23 23:55:32
表示位图像素的比特被打包成行。通过填充,每一行的大小被舍入为4个字节的倍数(32位DWORD)。
(bits_per_row + 31)/32 *4确保到32位的下一个倍数。答案是以字节为单位,而不是比特,因此*4而不是*32。
请参阅:格式化
发布于 2018-02-24 09:49:18
在位图头类型下,您可以找到以下内容:
扫描线为DWORD对齐.它们必须为扫描线宽度(以字节为单位)填充,这些宽度不能被4整除.例如,一个10×10像素的24-bpp位图将在每一行的末尾有两个填充字节.
公式
((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4建立DWORD-alignment (以字节为单位)。尾随的* 4实际上是* 32 / 8的结果,其中32的乘法产生的值是32的倍数(以位为单位),除法8将它转换回字节。
虽然这确实产生了所需的结果,但我更喜欢不同的实现。DWORD为32位,即2的幂。可以使用以下公式实现2的平方:
(value + ((1 << n) - 1)) & ~((1 << n) - 1)添加(1 << n) - 1会调整初始值,使其超过下一个n次方2(除非它已经是n次方2)。(1 << n) - 1计算为一个值,其中设置了n个最小位,~((1 << n) - 1)否定了这一点,即所有位,但n个最小位被设置。这用作消除调整初始值的n个最小有效位的掩码。
应用于这种特殊情况,其中DWORD为32位,即n为5,(1 << n) - 1计算为31。值是以位为单位的原始扫描线宽度:
auto raw_scanline_width_in_bits{ bmpScreen.bmWidth * bi.biBitCount };
auto aligned_scanline_width_in_bits{ (raw_scanline_width_in_bits + 31) & ~31 };
auto aligned_scanline_width_in_bytes{ raw_scanline_width_in_bits / 8 };这产生了相同的结果,但提供了一个不同的视角,这可能更容易为一些人所访问。
https://stackoverflow.com/questions/48957742
复制相似问题