How to get a screen image into a memory buffer?

大城市里の小女人 提交于 2019-12-11 20:11:13

问题


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. I'm now open to suggestions of libraries / classes that could do the "printing of a screen", but I should still have access to it's memory buffer.

Any help appreciated.

EDIT: I forgot to mention that I will be capturing the screen continuously, so the operation speed is very important. Maybe someone knows a good library for this?


回答1:


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.




回答2:


// 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);


来源:https://stackoverflow.com/questions/18858638/how-to-get-a-screen-image-into-a-memory-buffer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!