从CreateDIBSection
文档中,我发现CreateDIBSection
将指针指向BITMAPINFO
作为第二个参数。
但是,我遇到了各种各样的地方,表明它可能被允许传递指向其他结构(特别是BITMAPV5HEADER
)的指针,包括
我有一个感觉,这是非常有意义的( BITMAPV5HEADER
可以被看作是BITMAPINFO
结构布局的扩展版本),但是我找不到关于这个主题的官方文档。
任何人都可以确认传递BITMAPV5HEADER*
而不是BITMAPINFO
实际上是有效的,并可能提供一些文档?
简短的答案是否定的 。 BITMAPV5HEADER*
不是BITMAPINFO*
的替代品,无论何时只要BITMAPINFO*
是预期的(因为BITMAPINFO
包含调色板的颜色,而BITMAPV5HEADER
只是一个标题)。
如果BITMAPV5HEADER
是BITMAPINFO
的一部分,并且在它之后需要一些调色板颜色数据,那么传递BITMAPV5HEADER*
而不是BITMAPINFO*
当然是好的。 这是记录,虽然间接,通过使用指令和常识的一种:
BITMAPV5HEADER
被记录为“ BITMAPINFOHEADER
结构的扩展版本”,因此部分是清楚的。
BITMAPINFO
被记录为结合标题和颜色数据。 头是包含值而不是由指针,所以在这一点上很明显,头可能不会只是随便大小,否则将无法访问BITMAPINFO.bmiColors
和扩展版本的整个想法标题将是毫无意义的。
然后在文档的另一个地方解决这个问题(“备注”部分):
应用程序应该使用存储在
biSize
成员中的信息来定位BITMAPINFO
结构中的颜色表,如下所示:pColor = ((LPSTR)pBitmapInfo + (WORD)(pBitmapInfo->bmiHeader.biSize));
虽然我相信这一部分并没有让你感到困惑。
现在是漫长的回答。
BITMAPV5HEADER*
可以传递给BITMAPINFO*
时, 似乎有两种情况。 两者都没有以具体的方式记录下来,如果第一个我们可以应用上面应用的同样的常识,那么第二个似乎是文档中的一个错误:
BITMAPINFO.bmiColors
记录为NULL
。 您可以在BITMAPINFOHEADER
的文档中找到这些案例的完整列表。 当标题是BITMAPV4HEADER
或BITMAPV5HEADER
,位图具有16位或32位颜色,压缩设置为BI_BITFIELDS
。 在这种情况下,记录在标题后面的颜色蒙版取而代之,取自标题的相应专用字段,忽略标题DWORD
的三个DWORD
。
这很容易通过稍微修改原始代码来证明:
typedef struct tagV5BMPINFO { BITMAPV5HEADER bmiHeader; DWORD bmiColors[3]; } V5BMPINFO; int _tmain(int argc, _TCHAR* argv[]) { V5BMPINFO bmpinfo = { 0 }; BITMAPV5HEADER bmpheader = { 0 }; bmpheader.bV5Size = sizeof(BITMAPV5HEADER); bmpheader.bV5Width = width; bmpheader.bV5Height = height; bmpheader.bV5Planes = 1; bmpheader.bV5BitCount = 32; bmpheader.bV5Compression = BI_BITFIELDS; bmpheader.bV5SizeImage = 400*200*4; bmpheader.bV5RedMask = 0x00FF0000; bmpheader.bV5GreenMask = 0x0000FF00; bmpheader.bV5BlueMask = 0x000000FF; bmpheader.bV5AlphaMask = 0xFF000000; bmpheader.bV5CSType = 0x57696e20; // LCS_WINDOWS_COLOR_SPACE bmpheader.bV5Intent = LCS_GM_BUSINESS; bmpinfo.bmiHeader = bmpheader; // Put them in reverse order here compared to the above bmpinfo.bmiColors[0] = 0x000000FF; bmpinfo.bmiColors[1] = 0x0000FF00; bmpinfo.bmiColors[2] = 0x00FF0000; void* converted = NULL; HDC screen = GetDC(NULL); HBITMAP result = CreateDIBSection(screen, reinterpret_cast<BITMAPINFO*>(&bmpinfo), DIB_RGB_COLORS, &converted, NULL, 0); ReleaseDC(NULL, screen); DIBSECTION actual_data; GetObject(result, sizeof(actual_data), &actual_data); std::cout << std::hex; std::cout << actual_data.dsBitfields[0] << std::endl; std::cout << actual_data.dsBitfields[1] << std::endl; std::cout << actual_data.dsBitfields[2] << std::endl; std::cout << std::dec; DeleteObject(result); return 0; }
结果:
FF0000 FF00 FF
看起来文档是在BITMAPINFOHEADER
, BITMAPV4HEADER
和BITMAPV5HEADER
之间BITMAPV4HEADER
地复制的,应该在后两个版本中进行修改。 我能找到的最接近的解释是位图头类型至少可以识别专用掩码字段的存在,但仍然意味着必须在这些字段中提供值,并且在bmiColors
的头后:
BITMAPV4HEADER
位图的红色,绿色和蓝色位域掩码紧跟在BITMAPINFOHEADER
,BITMAPV4HEADER
和BITMAPV5HEADER
结构之后。BITMAPV4HEADER
和BITMAPV5HEADER
结构包含红色,绿色和蓝色掩码的其他成员,如下所示。
(强调我的)。
我们只能从证据中得出结论,这是不正确的。
它比我所希望的文档少。