【发布时间】:2018-03-15 16:48:10
【问题描述】:
我很难理解下面来自 MSDN 网站GetDIBits() 函数的摘录:
如果 lpvBits 为 NULL 且 BITMAPINFO 的位数成员为 初始化为零,GetDIBits 填充一个 BITMAPINFOHEADER 没有颜色表的结构或 BITMAPCOREHEADER。这 技术可用于查询位图属性。
问题1:“BITMAPINFO 的位数成员”是什么意思?是some_bmi.bmiHeader.biBitCount的意思吗?
问题 2:“GetDIBits 填充 BITMAPINFOHEADER 结构或没有颜色表的 BITMAPCOREHEADER”是什么意思? 有什么颜色表可以填充这些结构?他们似乎都没有与颜色表相关的成员。这是关于数组some_bmi.bmiColors吗?
问题 3:有没有办法使用GetDIBits() 来获取位图的颜色表(即数组映射索引到颜色)?
编辑:
从目前的 cmets 来看,将问题分解成更小的部分似乎没有效果。我会尝试另一种方式。
这是我从一开始引用MSDN的部分理解的:
假设函数调用为GetDIBits(hdc, hbmp, uStartScan, cScanLines, lpvBits, lpbi, uUsage);如果 lpvBits 为 NULL 且 lpvBits->bmiHeader.biBitCount 初始化为零,GetDIBits() 仅填写 lpbi->bmiHeader 而 lpbi->bmiColors 不会被修改。
这是理解它的正确方法吗?如果是这样,有没有办法让GetDIBits()填写lpbi->bmiColors,比如将lpvBits->bmiHeader.biBitCount初始化为位图的位深度?
我尝试如下测试 Question-1 的假设,但 GetDIBits() 在这种情况下失败:
void test(HWND hWnd) {
// get a memory DC
HDC hdc = GetDC(hWnd);
HDC hdcmem = CreateCompatibleDC(hdc); // has 1x1 mono bitmap selected
// into it initially by default
// select a 16x16 mono bmp into it
const int bmp_h = 16, bmp_w = 16;
const int bits_per_px = 1;
HBITMAP hbmp = CreateCompatibleBitmap(hdcmem, bmp_h, bmp_w); // 16x16 mono bitmap
HGDIOBJ hOldBmp = SelectObject(hdcmem, hbmp);
// initialize BITMAPINFO ptr
// (make sure to allocate a buffer large enough for 2 RGBQUADs
// in case color table is retured by GetDIBits() call)
const int bmi_buf_sz =
sizeof(BITMAPINFO) + sizeof(RGBQUAD) * (1 << bits_per_px); // 2 + 1(extra) RGBQUADs allocated for pbmi->bimColors
BYTE* p_bmi_buf = new BYTE[bmi_buf_sz];
BITMAPINFO* pbmi = reinterpret_cast<BITMAPINFO*>(p_bmi_buf);
ZeroMemory(pbmi, bmi_buf_sz);
// populate BITMAPINFO
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biBitCount = 1; // set to 1 just to see if GetDIBits()
// fills in pbmi->bmiColors too
// (when set to 0, only pbmi->bmiHeader is filled)
if(!GetDIBits(hdcmem, hbmp,
0, (UINT)bmp_h,
NULL, pbmi, DIB_PAL_COLORS)) {
MessageBox(hWnd, L"GetDIBits() failed!", NULL, MB_OK);
}
// clean-up
delete[] p_bmi_buf;
SelectObject(hdcmem, hOldBmp); // push hbmp out
DeleteObject(hbmp);
DeleteDC(hdcmem);
ReleaseDC(hWnd, hdc);
}
【问题讨论】:
-
所有这些在 MSDN 中都有详尽的解释。见Bitmaps。
-
@IInspectable :我已经阅读了整个“位图”部分以及几乎所有关于 GDI 的一般 MSDN 文档,但我仍然无法理解 OP 中引用的部分。我对 GDI 很陌生,而且我总是可能错过了一些东西。如果您能指出与我的问题相关的更具体的部分,我将不胜感激。
-
例如,对颜色表进行了非常详细的解释。 1-、2-、4- 和 8-bpp 位图具有颜色表,紧跟在
BITMAPINFO结构之后。 16 和更高的 bpp 位图没有颜色表。这回答了问题 2。链接中也回答了其他问题。也许你只需要再读一遍。 -
@IInspectable :我认为我已经掌握了这些部分。我担心可能是我的 OP 不够清楚。我的问题与引用部分的一般含义无关。只是在这些情况下它们对我来说没有意义。例如,我知道“颜色表”是什么,或者当它存在于位图中时它在哪里。我只是不明白“在没有颜色表的情况下填写
BITMAPINFOHEADER结构”是什么意思。BITMAPINFOHEADER不包含颜色表。它存储在BITMAPINFO的bmiColors数组成员中。 -
您正在将
BITMAPINFO结构传递给GetDIBits。