我有一个HBITMAP
,我想从具有相应BITMAPINFO
数组的HBITMAP
中获得完整的RGBQUAD
结构,而不仅仅是BITMAPINFOHEADER
。
这是BITMAPINFO
的结构:
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, *LPBITMAPINFO, *PBITMAPINFO;
我可以将GetDIBits
与NULL
指针一起使用以引用位缓冲区,以便将[[just BITMAPINFOHEADER
放入我分配的BITMAPINFO
存储器中。
RGBQUAD
数据计算BITMAPINFOHEADER
数组的大小,以便我可以分配足够的空间以允许GetDIBits
也存储整个数组。文档(以及我发现的许多代码示例)非常混乱,甚至在与该主题有关的某些部分上也有冲突。GetDIBits
和NULL
值作为像素缓冲区以获取BITMAPINFO
:BITMAPINFO* pbinfo = ( BITMAPINFO* ) malloc( sizeof( BITMAPINFOHEADER ) );
...
pbinfo->bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
GetDIBits( hScreenMemory, hBitmap, 0, 0, NULL, pbinfo, DIB_RGB_COLORS );
然后根据:
pbinfo->bmiHeader.biBitCount
pbinfo->bmiHeader.biClrUsed
pbinfo->bmiHeader.biCompression
RGBQUAD
个数组元素的数量:DWORD ColorTableLength( BITMAPINFOHEADER* h ) {
DWORD result = 0;
DWORD biClrUsed = h->biClrUsed;
WORD biBitCount = h->biBitCount;
DWORD biCompression = h->biCompression;
switch ( biBitCount ) {
case 24:
result = biClrUsed;
break;
case 16:
case 32:
if ( biCompression == BI_RGB )
result = biClrUsed;
else if ( biCompression == BI_BITFIELDS )
result = 3;
break;
default: // for 0, 1, 2, 4, and 8
if ( biClrUsed == 0 )
result = ( 1 << biBitCount ); // 2^biBitCount
else
result = biClrUsed;
break;
}
return result;
}
这是“最低公分母”,在许多资源和我在网上找到的示例之间都是一致的(并且仍然有可能不适用于每种情况。
需要为RGBQUAD
数组分配的字节数可以通过sizeof(RGBQUAD) * ColorTableLength( &... )
来计算。[在某些情况下
RGBQUAD
数组被3个DWORD
替换,但是DWORD
和RGBQUAD
的大小相同,因此我们将sizeof
与ColorTableLength
值相乘并不重要。] >[我不确定为什么标准没有定义一个字段,该字段明确指出为颜色表/
RGBQUAD
数组/ RGBDWORD
保留了多少字节,但是看起来就是这样。
biClrUsed
字段应该有此目的,但并非在所有情况下都如此。