2012-10-11 21 views
10

Contexto: Estoy tratando de tomar una captura de pantalla de otra ventana para alimentarlo en OpenCV. Encontré un código en la web que debería poder convertir un BITMAP en algo con lo que OpenCV pueda trabajar. Lamentablemente me encontré con algunos problemas.¿Por qué GetObject devuelve un BITMAP con null bmBits?

Pregunta: ¿Por qué el atributo/miembro bmBits siempre es nulo? (I también intentado con PrintWindow en lugar de BitBlt el resultado fue el mismo)

#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

¿Está tratando de hacer una captura de pantalla con este código, solo fuera de la mano? Lo parece. PrintWindow no es lo que necesita si ese es el caso. Todo lo que hace es enviar una WM_PRINT a la ventana de destino con un DC en el que volcar. No hay garantía de que la ventana procesará ese mensaje, y si es así, haga lo que quiera. Casi tiene todo lo que necesita, pero creo que necesita usar un BitBlt() para extraer bits de la pantalla DC a su DC compatible con su mapa de bits nuevo listo para recibirlos. – WhozCraig

Respuesta

16

El miembro bmBits no es nulo para las secciones DIB. Para los mapas de bits dependientes del dispositivo (como el que está creando), el bmBits no está configurado porque los píxeles están en la tarjeta de video, no en la memoria principal.

En su ejemplo, debe cambiar CreateCompatibleBitmap a CreateDIBSection si desea acceso directo a los bits.

7

Solo para obtener información. Al cargar mapa de bits de un archivo y desea utilizar BITMAP .bmBits (por glTexImage2D, glDrawPixels):

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

u debe especificar bandera 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

Esta es la única respuesta que he visto que menciona esto. Usted, señor, es increíble! –

-1

Una cosa que se podía hacer es mirar el valor de retorno de GetObject. Si 0 sabes que algo salió mal. Algo malo con los parámetros de la llamada.

0

De GetObject documentación en MSDN. Por favor, tenga en cuenta el segundo párrafo.

Si hgdiobj es un identificador para un mapa de bits creado por llamar CreateDIBSection, y el búfer especificado es lo suficientemente grande, la función deGetObject devuelve una estructura DIBSECTION. Además, el bmBits miembro de la estructura BITMAP contenida en DIBSECTION contendrá un puntero a los valores de bits del mapa de bits.

Si hgdiobj es un identificador para un mapa de bits creado por cualquier otro medio, GetObject devoluciones solamente la anchura, la altura y la información del formato de color del mapa de bits. Puede obtener los valores de bit del mapa de bits llamando a la función GetDIBits o GetBitmapBits.

Cuestiones relacionadas