Работа с растровыми изображениями очень полезна для меня, поэтому я действительно борюсь с онлайн-учебниками и стратегиями, которые я прочитал. В основном моя цель - сканировать экран для определенного значения RGB. Я считаю, что шаги для этого - захватить экран в hBitmap, а затем создать из него массив значений RGB, которые я могу проверить.C++ Получение RGB из hBitmap
Первоначально я начал с GetPixel, но это очень медленно. Решением было использование GetDIBits, которое создает массив значений RGB. Проблема в том, что он возвращает странные и, возможно, случайные значения RGB.
Я использую следующий код, который я нашел из другого учебника:
/* 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)];
}
я проверить это с помощью следующего кода. Я нажал Shift, чтобы вызвать ScreenCap, а затем переместите курсор в нужное место и нажмите «Пробел», чтобы увидеть, какое значение RGB находится в этом месте. Я совершенно орехи?
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;
}
Вы запрашиваете RGB, но ваш код, кажется, обрабатывать данные, как BGR , –
Из того, что я читал, я считаю, что природа GetDIBits возвращает их в этом порядке. Но, я думаю, я должен указать, что даже если бы я тестировал на полностью черно-белом экране, где все r = g = b, значения rgb все равно кажутся случайными. Таким образом, он будет сообщать о черном, когда он на самом деле белый, и белый, когда иногда бывает черным. – Mike
Возможный дубликат [GetDIBits и циклические пиксели с использованием X, Y] (http://stackoverflow.com/questions/3688409/getdibits-and-loop-through-pixels-using-xy) – sashoalm