Win32 BITMAPINFO如何可靠地为RGBQUAD数组/颜色表(bmiColors字段)分配足够的内存?

问题描述 投票:0回答:1

我有一个HBITMAP,我想从具有相应BITMAPINFO数组的HBITMAP中获得完整的RGBQUAD结构,而不仅仅是BITMAPINFOHEADER

这是BITMAPINFO的结构:

typedef struct tagBITMAPINFO {
  BITMAPINFOHEADER bmiHeader;
  RGBQUAD          bmiColors[1];
} BITMAPINFO, *LPBITMAPINFO, *PBITMAPINFO;

我可以将GetDIBitsNULL指针一起使用以引用位缓冲区,以便将[[just BITMAPINFOHEADER放入我分配的BITMAPINFO存储器中。

我不知道的是,如何[[可靠地RGBQUAD数据计算BITMAPINFOHEADER数组的大小,以便我可以分配足够的空间以允许GetDIBits也存储整个数组。文档(以及我发现的许多代码示例)非常混乱,甚至在与该主题有关的某些部分上也有冲突。
winapi colors bitmap
1个回答
0
投票
使用GetDIBitsNULL值作为像素缓冲区以获取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
  1. 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替换,但是DWORDRGBQUAD的大小相同,因此我们将sizeofColorTableLength值相乘并不重要。] >

    [我不确定为什么标准没有定义一个字段,该字段明确指出为颜色表/ RGBQUAD数组/ RGB DWORD保留了多少字节,但是看起来就是这样。

    biClrUsed字段应该有此目的,但并非在所有情况下都如此。

  • © www.soinside.com 2019 - 2024. All rights reserved.