应该为使用GetDIBits函数从HBITMAP接收的DIB数据分配多少内存

How much memory should be allocated for the DIB data received from HBITMAP using GetDIBits function?

本文关键字:DIB 数据 分配 内存 多少 HBITMAP GetDIBits 函数      更新时间:2023-10-16

应该为使用GetDIBits函数从HBITMAP接收的DIB数据分配多少内存?

GetDIBits函数在MSDN中描述如下:

int GetDIBits(
  __in     HDC hdc,
  __in     HBITMAP hbmp,
  __in     UINT uStartScan,
  __in     UINT cScanLines,
  __out    LPVOID lpvBits,
  __inout  LPBITMAPINFO lpbi,
  __in     UINT uUsage
);

然而,接收数据lpvBits的缓冲区必须在调用GetDIBits之前分配,因为GetDIBits不会自动分配。

问题是应该分配多少内存来接收DIB数据?假设HBITMAP的width&height为Bmp_Width&Bmp_Height;位图为32位(RGBA)。

我认为最简单的方法是调用GetObject()函数(顺便说一句,以获得图像位):

BITMAP bmpObject;
GetObject(hBitmap, sizeof(BITMAP), &bmpObject);

然后你只需使用位图字段:

LONG size = bmpObject.bmWidthBytes * bmpObject.bmHeight;

处理图像字节时要注意对齐!

希望这将是有用的!

lpvBits所指向的内存必须是一个扫描行的大小乘以高度。每个扫描线必须在DWORD边界上对齐。

既然你使用的是32位彩色,那么每条扫描线自然会满足这个要求,只要你确保第一条扫描线,即内存块的开始,是4字节对齐的。

因此,以字节为单位测量的答案是4*宽度*高度,从4字节边界开始对齐。

biSizeImage包含位图的大小,以字节为单位或值0。0表示DIB的大小为默认值。计算位图的大小并不困难:

biSizeImage = ((((biWidth * biBitCount) + 31) & ~31) >> 3) * biHeight:

疯狂的四舍五入和移位说明位图是在每条扫描线的末尾与dword对齐。当非零时,这个场告诉应用程序DIB的位需要多少存储空间。的biSizeImage字段在处理RLE时非常有用位图,其大小取决于位图编码的好坏。如果要传递RLE位图,则biSizeImage字段为强制性的。

每个扫描线都与dword对齐。扫描线被缓冲到对齐;缓冲区不一定是0.

盖瑞,罗恩。"dib及其使用。"MSDN技术集团,1992年3月20日,https://learn.microsoft.com/previous-versions/ms969901(v=msdn.10).