我试图从鼠标光标获取位图,但下一个代码,我只是无法获得颜色。
CURSORINFO cursorInfo = { 0 }; cursorInfo.cbSize = sizeof(cursorInfo); if (GetCursorInfo(&cursorInfo)) { ICONINFO ii = {0}; int p = GetIconInfo(cursorInfo.hCursor, &ii); // get screen HDC dc = GetDC(NULL); HDC memDC = CreateCompatibleDC(dc); //SelectObject(memDC, ii.hbmColor); int counter = 0; // byte* bits[1000];// = new byte[w * 4]; BITMAPINFO bmi; memset(&bmi, 0, sizeof(BITMAPINFO)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = 16; bmi.bmiHeader.biHeight = 16; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biSizeImage = 0; bmi.bmiHeader.biXPelsPerMeter = 0; bmi.bmiHeader.biYPelsPerMeter = 0; bmi.bmiHeader.biClrUsed = 0; bmi.bmiHeader.biClrImportant = 0; int rv = ::GetDIBits(memDC, ii.hbmColor, 0, 1, (void**)&bits, &bmi, DIB_RGB_COLORS); }
首先获取Windows所记录的位图参数:
BITMAP bitmap = {0}; GetObject(ii.hbmColor, sizeof(bitmap), &bitmap);
您可以使用返回的值来填充bmi
结构。
而关于bmi
结构: BITMAPINFO
并没有为调色板预留足够的空间。 你应该为此创建自己的结构:
struct BitmapPlusPalette { BITMAPINFOHEADER bmiHeader; RGBQUAD palette[256]; };
计算位图所需的字节数有点棘手,因为它需要四舍五入:
w = ((bitmap.bmWidth * bitmap.bmBitsPixel) + 31) / 8; byte* bits = new byte[w * bitmap.bmHeight];
这里是最后一行的更正版本:
int rv = ::GetDIBits(dc, ii.hbmColor, 0, bitmap.bmHeight, bits, (BITMAPINFO *)&bmi, DIB_RGB_COLORS);
我认为你的代码的问题是你为内存分配'bits'变量的方式,以及你如何在GetDIBits函数中使用它。
首先,注释部分byte* bits = new byte[w*4]
优于byte* bits[1000]
。 当你写byte* bits[1000]
计算机分配1000个指针到字节。 这些指针中的每一个都不指向任何东西。
其次,GetDIBits接受LPVOID lpvBits作为第五参数。 所以,它的一个指针无效。 在大多数平台中sizeof(void *)> sizeof(byte),所以你不能只是传递一个字节数组,可能最好是将指针传递给int或unsigned int(我不擅长Windows类型,所以也许更合适的东西应该更好,抱歉)。
所以,我的猜测是这样的:
unsigned bits[1000]; memset(bits, 0, sizeof(bits)); //... int tv = GetDIBits(memDC, ii.hmbColor, 0, 1, (LPVOID)bits, /* ... */);