How to get a screen image into a memory buffer?

后端 未结 2 463
孤独总比滥情好
孤独总比滥情好 2020-12-22 09:41

I\'ve been searching for a pure WIN32 way of getting the image data of a screen into a buffer, for analysis of the objects in the image later... Sadly I haven\'t found any.

相关标签:
2条回答
  • 2020-12-22 09:57

    There are multiple ways (you could use DirectX), but probably the simplest and easiest is to use GDI.

        // GetDC(0) will return screen device context
        HDC hScreenDC = GetDC(0);
        // Create compatible device context which will store the copied image
        HDC hMyDC= CreateCompatibleDC(hScreenDC );
    
        // Get screen properties
        int iScreenWidth = GetSystemMetrics(SM_CXSCREEN);
        int iScreenHeight = GetSystemMetrics(SM_CYSCREEN);
        int iBpi= GetDeviceCaps(hScreenDC ,BITSPIXEL);
    
        // Fill BITMAPINFO struct
        BITMAPINFO info;
        info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        info.bmiHeader.biWidth = iScreenWidth;
        info.bmiHeader.biHeight = iScreenHeight ;
        info.bmiHeader.biPlanes = 1;
        info.bmiHeader.biBitCount  = iBpi;
        info.bmiHeader.biCompression = BI_RGB;
    
        // Create bitmap, getting pointer to raw data (this is the important part)
        void *data;
        hBitmap = CreateDIBSection(hMyDC,&info,DIB_RGB_COLORS,(void**)&data,0,0);
        // Select it into your DC
        SelectObject(hMyDC,hBitmap);
    
        // Copy image from screen
        BitBlt(hMyDC, 0, 0, iScreenWidth, iScreenHeight, hScreenDC , 0, 0, SRCCOPY);
    
        // Remember to eventually free resources, etc.
    

    It's been a while since I did this so I may be forgetting something, but that's the gist of it. A word of warning: this is NOT fast; when the screen is moving a lot, it may take 50ms or more to capture one frame. It's basically doing the equivalent of pressing the PrintScreen key.

    0 讨论(0)
  • 2020-12-22 10:06
    // get screen DC and memory DC to copy to
    HDC hScreenDC = GetDC(0);
    HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
    
    // create a DIB to hold the image
    BITMAPINFO bmi = { 0 };
    bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
    bmi.bmiHeader.biWidth = GetDeviceCaps(hScreenDC, HORZRES);
    bmi.bmiHeader.biHeight = -GetDeviceCaps(hScreenDC, VERTRES);
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 32;
    LPVOID pBits;
    HBITMAP hBitmap = CreateDIBSection(hMemoryDC, &bmi, DIB_RGB_COLORS, &pBits, NULL, 0);
    
    // select new bitmap into memory DC
    HGDIOBJ hOldBitmap = SelectObject(hMemoryDC, hBitmap);
    
    // copy from the screen to memory
    BitBlt(hMemoryDC, 0, 0, bmi.bmiHeader.biWidth, -bmi.bmiHeader.biHeight, hScreenDC, 0, 0, SRCCOPY);
    
    // clean up
    SelectObject(hMemoryDC, hOldBitmap);
    DeleteDC(hMemoryDC);
    ReleaseDC(0, hScreenDC);
    
    // the image data is now in pBits in 32-bpp format
    // free this when finished using DeleteObject(hBitmap);
    
    0 讨论(0)
提交回复
热议问题