C++ Immer RGB aus hBitmap
Arbeiten mit bitmaps ist sehr neu für mich, so ich ' ve wurde wirklich kämpfen mit den online-tutorials und Strategien, die ich gelesen habe, durch. Im Grunde ist mein Ziel, Scannen Sie den Bildschirm für einen bestimmten RGB-Wert. Ich glaube, die Schritte, um dies zu tun ist, zum aufnehmen des Bildschirms in ein hBitmap, und dann ein array der RGB-Werte aus, ich kann scan durch.
Ich begann ursprünglich mit GetPixel aber das ist sehr langsam. Die Lösung war die Verwendung GetDIBits erzeugt das array der RGB-Werte. Das problem ist, dass es gibt seltsame und möglicherweise beliebige RGB-Werte statt.
Ich bin mit dem folgenden code die ich gefunden aus einem anderen tutorial:
/* 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)];
}
Ich Teste dies mit folgendem code. Drücke ich Shift zum aufrufen ScreenCap und dann bewege ich meinen Mauszeiger an die gewünschte Position und drücke Space, um zu sehen, was der RGB-Wert wird an dieser Position ein. Bin ich komplett verrückt?
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;
}
- Fordern Sie RGB, aber dein code scheint zu sein, die Behandlung der Daten der BGR.
- Von dem, was ich gelesen habe, glaube ich, dass die Natur von GetDIBits gibt Sie in dieser Reihenfolge. Aber ich denke, ich sollte darauf hinweisen, dass selbst wenn ich getestet habe, auf einen komplett schwarzen/weißen Bildschirm, wo alle r=g=b ist, die rgb-Werte immer noch, scheint zufällig zu sein. Also es melden würde schwarz, wenn er tatsächlich weiß, und weiß, wenn es tatsächlich manchmal schwarz.
- mögliche Duplikate von GetDIBits und Schleife über die Pixel mit X, Y
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das Problem ist, dass dein Bildschirm ist tatsächlich 32-bit tief und nicht 24. Der folgende code geben Sie das Ergebnis Sie brauchen:
Dein Bild Größe ist angegeben in Pixel, es sollte angegeben werden, in bytes
biSizeImage seiner definierten Einheiten sind bytes und geben Sie RGB 3 Byte pro pixel.
http://msdn.microsoft.com/en-us/library/windows/desktop/dd183376(v=vs. 85).aspx
biSizeImage
Die Größe, in bytes, der Bild. Dies kann auf null gesetzt werden für BI_RGB bitmaps.