从the documentation on CreateDIBSection
中,我观察到CreateDIBSection
将指向BITMAPINFO
的指针作为第二个参数。
但是,我遇到了很多地方,表明可能允许它将指针传递给其他结构(特别是BITMAPV5HEADER
),包括
我感觉这很合理(可以将
BITMAPV5HEADER
视为BITMAPINFO
wrt结构布局的“扩展版本”),但是我找不到关于该主题的任何官方文档。有人可以确认传递
BITMAPV5HEADER*
而不是BITMAPINFO
实际上是有效的,并且可能提供一些文档吗? 最佳答案
简短的答案必须为否。 BITMAPV5HEADER*
不能替代BITMAPINFO*
,并且每当需要BITMAPINFO*
时都可能无法传递ojit(原因是BITMAPINFO
在 header 之后包含调色板颜色,而BITMAPV5HEADER
只是 header )。
如果BITMAPV5HEADER*
是BITMAPINFO*
的一部分并在其后需要某种调色板颜色数据,则传递BITMAPV5HEADER
而不是BITMAPINFO
当然很好。通过使用说明和常识可以间接地记录下来:
BITMAPV5HEADER
是documented,是“BITMAPINFOHEADER
结构的扩展版本”,因此该部分很清楚。 BITMAPINFO
是documented,用于组合标题和颜色数据。 header 包含值,而不是指针,因此很明显 header 可能不只是随便增加大小,否则将无法访问BITMAPINFO.bmiColors
和拥有 header 扩展版本的整个想法毫无意义。 尽管我相信这部分不会让您开始感到困惑。
现在长答案。
可以将
BITMAPV5HEADER*
传递给BITMAPINFO*
似乎有两种情况。两者均未以具体方式记录,并且如果对于第一个,我们可以应用与上面所应用的相同的常识,则第二个似乎是文档中的错误:BITMAPINFO.bmiColors
被记录为NULL
时。您可以在documentation for BITMAPINFOHEADER
中找到此类案例的完整列表。 BITMAPV4HEADER
或BITMAPV5HEADER
时,位图具有16或32位颜色,并且压缩设置为BI_BITFIELDS
。在那种情况下,记录在标题之后的颜色掩码取而代之的是从标题的各个专用字段中获取,并且忽略标题之后的三个DWORD
。通过稍微修改original code可以很容易地证明这一点:
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
之间。我能找到的最接近的解释是Bitmap Header Types,它至少可以识别专用掩码字段的存在,但仍然暗示必须在这些字段中以及bmiColors
的 header 之后提供值:(强调我的)。
我们只能从证据中得出结论,那就是事实并非如此。
它比我希望的要少的文档。
关于windows - Windows位图: BITMAPV5HEADER and BITMAPINFO compatible?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46338924/