2012-10-11 2 views
10

Kontext: Ich versuche, einen Screenshot von einem anderen Fenster zu machen, um es in OpenCV zu füttern. Ich habe Code im Internet gefunden, der in der Lage sein sollte, eine BITMAP in etwas zu konvertieren, mit dem OpenCV arbeiten kann. Leider geriet ich in Schwierigkeiten.Warum gibt GetObject eine BITMAP mit null bmBits zurück?

Frage: Warum ist das Attribut bmBits/member immer null? (I auch versucht, mit Printwindow anstelle von BitBlt war das Ergebnis das gleiche)

#include <iostream> 
#include <string> 
#include <Windows.h> 

int main(int argc, char* argv[]) 
{ 
    std::wstring windowName = L"Calculator"; 

    RECT rect; 
    HWND hwnd = FindWindow(NULL, windowName.c_str()); 
    if (hwnd == NULL) 
    { 
     return 0; 
    } 
    GetClientRect(hwnd, &rect); 

    HDC hdcScreen = GetDC(NULL); 
    HDC hdc = CreateCompatibleDC(hdcScreen); 
    HBITMAP hbmp = CreateCompatibleBitmap(hdcScreen, 
     rect.right - rect.left, rect.bottom - rect.top); 
    SelectObject(hdc, hbmp); 

    PrintWindow(hwnd, hdc, PW_CLIENTONLY); 

    BITMAP bmp; 
    GetObject(hbmp, sizeof(BITMAP), &bmp); 

    return 0; 
} 
+0

Versuchen Sie, einen Screenshot mit diesem Code zu erstellen, nur aus der Hand? Schaut so aus. PrintWindow ist nicht das, was Sie brauchen, wenn das der Fall ist. Es sendet lediglich ein WM_PRINT an das Zielfenster mit einem DC, auf dem ein Dump erfolgen soll. Es gibt keine Garantie, dass das Fenster diese Nachricht überhaupt verarbeitet, und wenn ja, tun Sie, was Sie wollen. Sie haben fast alles, was Sie brauchen, aber ich glaube, Sie müssen ein BitBlt() verwenden, um Bits von dem Bildschirm DC zu Ihrem kompatiblen DC mit Ihrer frischen Bitmap zu ziehen, bereit, sie zu empfangen. – WhozCraig

Antwort

16

Das bmBits Mitglied ist nicht-null für DIB Abschnitte. Bei geräteabhängigen Bitmaps (z. B. dem von Ihnen erstellten) wird bmBits nicht festgelegt, da sich die Pixel auf der Grafikkarte und nicht im Hauptspeicher befinden.

In Ihrem Beispiel müssen Sie zu CreateDIBSection ändern, wenn Sie direkten Zugriff auf die Bits wünschen.

7

Nur zur Information. Wenn Bitmap aus einer Datei geladen und wollen BITMAP .bmBits verwenden (für glTexImage2D, glDrawPixels):

LoadImage(NULL, "path_to.bmp", IMAGE_BITMAP, 0, 0, 
             LR_LOADFROMFILE); 

u LR_CREATEDIBSECTION

HBITMAP hBmp = NULL; 
BITMAP BMp; 
hBmp = (HBITMAP) LoadImage(NULL, "bitmap.bmp", IMAGE_BITMAP, 0, 0, 
             LR_LOADFROMFILE | LR_CREATEDIBSECTION); 
GetObject(hBmp, sizeof(BMp), &BMp); 
//BMp.bmBits now points to data 
+0

Dies ist die einzige Antwort, die ich je gesehen habe, die dies erwähnt. Sie, Herr, sind fantastisch! –

-1

Eine Sache, die Sie könnten angeben Flag muss Sehen Sie sich den Rückgabewert von GetObject an. Wenn Sie wissen, dass etwas schiefgelaufen ist. Etwas stimmt nicht mit den Parametern des Anrufs.

0

Von GetObject Dokumentation auf MSDN. Bitte beachten Sie den zweiten Absatz.

Wenn hgdiobj ist ein Handgriff in einer Bitmap durch Aufruf CreateDIBSection erstellt, und der angegebene Puffer ist groß genug, die GetObject Funktion gibt eine DIBSECTION Struktur. Zusätzlich enthält das bmBits Mitglied der BITMAP Struktur, die in DIBSECTION enthalten ist, einen Zeiger auf die Bitmap-Bitwerte.

Wenn hgdiobj ist ein Handgriff in eine Bitmap durch irgendwelche anderen Mittel erstellt, GetObject kehrt nur die Breite, Höhe und Farbe Formatinformation der Bitmap. Sie können die Bitwerte der Bitmap abrufen, indem Sie die Funktion GetDIBits oder GetBitmapBits aufrufen.

Verwandte Themen