Làm việc với bitmap rất mới đối với tôi vì vậy tôi đã thực sự đấu tranh với các hướng dẫn và chiến lược trực tuyến mà tôi đã đọc qua. Về cơ bản mục tiêu của tôi là quét màn hình cho một giá trị RGB cụ thể. Tôi tin rằng các bước để làm điều này là chụp màn hình trong hBitmap và sau đó tạo ra một mảng các giá trị RGB từ nó mà tôi có thể quét qua.C++ Bắt RGB từ hBitmap
Ban đầu tôi bắt đầu với GetPixel nhưng điều đó rất chậm. Giải pháp là sử dụng GetDIBits tạo ra mảng giá trị RGB. Vấn đề là nó trả về các giá trị RGB ngẫu nhiên và có thể ngẫu nhiên thay thế.
Tôi đang sử dụng đoạn mã sau đó tôi thấy từ hướng dẫn khác:
/* Globals */
int ScreenX = GetDeviceCaps(GetDC(0), HORZRES);
int ScreenY = GetDeviceCaps(GetDC(0), VERTRES);
BYTE* ScreenData = new BYTE[3*ScreenX*ScreenY];
void ScreenCap() {
HDC hdc = GetDC(GetDesktopWindow());
HDC hdcMem = CreateCompatibleDC (hdc);
HBITMAP hBitmap = CreateCompatibleBitmap(hdc, ScreenX, ScreenY);
BITMAPINFOHEADER bmi = {0};
bmi.biSize = sizeof(BITMAPINFOHEADER);
bmi.biPlanes = 1;
bmi.biBitCount = 24;
bmi.biWidth = ScreenX;
bmi.biHeight = -ScreenY;
bmi.biCompression = BI_RGB;
bmi.biSizeImage = ScreenX * ScreenY;
SelectObject(hdcMem, hBitmap);
BitBlt(hdcMem, 0, 0, ScreenX, ScreenY, hdc, 0, 0, SRCCOPY);
GetDIBits(hdc, hBitmap, 0, ScreenY, ScreenData, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
DeleteDC(hdcMem);
ReleaseDC(NULL, hdc);
}
inline int PosR(int x, int y) {
return ScreenData[3*((y*ScreenX)+x)+2];
}
inline int PosG(int x, int y) {
return ScreenData[3*((y*ScreenX)+x)+1];
}
inline int PosB(int x, int y) {
return ScreenData[3*((y*ScreenX)+x)];
}
tôi thử nghiệm này với đoạn mã sau. Tôi nhấn Shift để gọi ScreenCap và sau đó tôi di chuyển con trỏ đến vị trí mong muốn và nhấn Space để xem giá trị RGB ở vị trí đó. Tôi có hoàn toàn không?
int main() {
while (true) {
if (GetAsyncKeyState(VK_SPACE)){
// Print out current cursor position
GetCursorPos(&p);
printf("X:%d Y:%d \n",p.x,p.y);
// Print out RGB value at that position
int r = PosR(p.x, p.y);
int g = PosG(p.x, p.y);
int b = PosB(p.x, p.y);
printf("r:%d g:%d b:%d \n",r,g,b);
} else if (GetAsyncKeyState(VK_ESCAPE)){
printf("Quit\n");
break;
} else if (GetAsyncKeyState(VK_SHIFT)){
ScreenCap();
printf("Captured\n");
}
}
system("PAUSE");
return 0;
}
Bạn đang yêu cầu RGB, nhưng mã của bạn dường như được coi tài liệu như BGR . –
Từ những gì tôi đã đọc, tôi tin rằng bản chất của GetDIBits trả về chúng theo thứ tự đó. Nhưng tôi đoán tôi nên chỉ ra rằng ngay cả khi tôi thử nghiệm trên một màn hình hoàn toàn màu đen/trắng, nơi tất cả r = g = b, các giá trị rgb vẫn có vẻ là ngẫu nhiên. Vì vậy, nó sẽ báo cáo màu đen khi nó thực sự trắng, và trắng khi nó thực sự là màu đen đôi khi. – Mike
có thể trùng lặp của [GetDIBits và lặp qua pixel bằng X, Y] (http://stackoverflow.com/questions/3688409/getdibits-and-loop-through-pixels-using-xy) – sashoalm