hBitmap = (HBITMAP)SelectObject(hdcMemory, hBitmapOld);
这将覆盖
hBitmap
,你不会想要的。您应该将该行更改为:
SelectObject(hdcMemory, hBitmapOld);
然后您可以使用
GetDIBits
此外,您已经将位图复制到内存dc。您可以使用
GetPixel
获取颜色。没有必要打电话
GetDIBits公司
HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMemory, hBitmap);
COLORREF color = GetPixel(hdcMemory, x, y);
BYTE red = GetRValue(color);
BYTE green = GetGValue(color);
BYTE blue = GetBValue(color);
...
SelectObject(hdcMemory, hBitmapOld);
DeleteObject(hBitmap);
DeleteDC(hdcMemory);
RleaseDC(0, hdcSource);
完成后,也可以致电
DeleteObject(hBitmap)
使用
GetDIBits公司
:32位位图格式为BGRA而非RGBA,因此第一个字节为蓝色而非红色。在将位视为32位位图之前,应特别请求32位位图或检查位计数。
#include <iostream>
#include <vector>
#include <Windows.h>
int main()
{
HWND target = FindWindow("Notepad", 0);
if(!target)
{
printf("error, no window\n");
return 0;
}
RECT rc;
GetWindowRect(target, &rc);
int x = rc.left;
int y = rc.top;
int w = rc.right - rc.left;
int h = rc.bottom - rc.top;
int screen_w = GetSystemMetrics(SM_CXFULLSCREEN);
int screen_h = GetSystemMetrics(SM_CYFULLSCREEN);
HDC hdc = GetDC(HWND_DESKTOP);
HBITMAP hbitmap = CreateCompatibleBitmap(hdc, screen_w, screen_h);
HDC memdc = CreateCompatibleDC(hdc);
HGDIOBJ oldbmp = SelectObject(memdc, hbitmap);
BitBlt(memdc, 0, 0, w, h, hdc, x, y, CAPTUREBLT | SRCCOPY);
SelectObject(memdc, oldbmp);
BITMAPINFOHEADER infohdr = { sizeof(infohdr), w, h, 1, 32 };
int size = w * h * 4;
std::vector<BYTE> bits(size);
int res = GetDIBits(hdc, hbitmap, 0, h, &bits[0],
(BITMAPINFO*)&infohdr, DIB_RGB_COLORS);
if(res != h)
{
std::cout << "error\n";
return 0;
}
BYTE *ptr = bits.data();
//for(y = 0; y < h; y++)
for(y = h - 1; y >= 0; y--) //bitmaps bits start from bottom, not top
{
for(x = 0; x < w; x++)
{
BYTE blu = ptr[0];
BYTE grn = ptr[1];
BYTE red = ptr[2];
ptr += 4;
}
}
SelectObject(memdc, oldbmp);
DeleteObject(hbitmap);
ReleaseDC(HWND_DESKTOP, hdc);
DeleteDC(memdc);
return 0;
}
注意,如果用户未使用默认DPI设置,则该过程应支持DPI。