Take a screenshot of the screen using gpu.

asked 2020-10-20 14:42:02 -0500

Good afternoon. I am trying to modify the function so that it wastes gpu and not cpu. Here is its initial view.

Mat hwnd2mat(HWND hwnd)
{
HDC hwindowDC, hwindowCompatibleDC;

int height, width, srcheight, srcwidth;
HBITMAP hbwindow;
Mat src;
BITMAPINFOHEADER  bi;

hwindowDC = GetDC(hwnd);
hwindowCompatibleDC = CreateCompatibleDC(hwindowDC);
SetStretchBltMode(hwindowCompatibleDC, COLORONCOLOR);

RECT windowsize;    // get the height and width of the screen
GetClientRect(hwnd, &windowsize);

srcheight = windowsize.bottom;
srcwidth = windowsize.right;
height = windowsize.bottom / 1;  //change this to whatever size you want to resize to
width = windowsize.right / 1;

src.create(height, width, CV_8UC4);

// create a bitmap
hbwindow = CreateCompatibleBitmap(hwindowDC, width, height);
bi.biSize = sizeof(BITMAPINFOHEADER);    //http://msdn.microsoft.com/en-us/library/windows/window/dd183402%28v=vs.85%29.aspx
bi.biWidth = width;
bi.biHeight = -height;  //this is the line that makes it draw upside down or not
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;

// use the previously created device context with the bitmap
SelectObject(hwindowCompatibleDC, hbwindow);
// copy from the window device context to the bitmap device context
StretchBlt(hwindowCompatibleDC, 0, 0, width, height, hwindowDC, 0, 0, srcwidth, srcheight, SRCCOPY); //change SRCCOPY to NOTSRCCOPY for wacky colors !
GetDIBits(hwindowCompatibleDC, hbwindow, 0, height, src.data, (BITMAPINFO*)&bi, DIB_RGB_COLORS);  //copy from hwindowCompatibleDC to hbwindow

// avoid memory leak
DeleteObject(hbwindow);
DeleteDC(hwindowCompatibleDC);
ReleaseDC(hwnd, hwindowDC);

return src;
}

Here's how I change it, but nothing works for me. So that you do not look for a long time what exactly I am to change, then I will write. I changed

Mat src = UMat src
src.create (height, width, CV_8UC4) = src.create (height, width, CV_8UC4, USAGE_ALLOCATE_DEVICE_MEMORY);
GetDIBits (hwindowCompatibleDC, hbwindow, 0, height, src.data, (BITMAPINFO *) & bi, DIB_RGB_COLORS) = GetDIBits (hwindowCompatibleDC, hbwindow, 0, height, src.u-> data, (BITMAPINFO_R *); & bi_DIBOLORS

All Code:

UMat hwnd2mat(HWND hwnd)
{
HDC hwindowDC, hwindowCompatibleDC;

int height, width, srcheight, srcwidth;
HBITMAP hbwindow;
UMat src;
BITMAPINFOHEADER  bi;

hwindowDC = GetDC(hwnd);
hwindowCompatibleDC = CreateCompatibleDC(hwindowDC);
SetStretchBltMode(hwindowCompatibleDC, COLORONCOLOR);

RECT windowsize;    // get the height and width of the screen
GetClientRect(hwnd, &windowsize);

srcheight = windowsize.bottom;
srcwidth = windowsize.right;
height = windowsize.bottom / 1;  //change this to whatever size you want to resize to
width = windowsize.right / 1;

src.create(height, width, CV_8UC4, USAGE_ALLOCATE_DEVICE_MEMORY);

// create a bitmap
hbwindow = CreateCompatibleBitmap(hwindowDC, width, height);
bi.biSize = sizeof(BITMAPINFOHEADER);    //http://msdn.microsoft.com/en-us/library/windows/window/dd183402%28v=vs.85%29.aspx
bi.biWidth = width;
bi.biHeight = -height;  //this is the line that makes it draw upside down or not
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;

// use the previously created device context with the bitmap
SelectObject(hwindowCompatibleDC, hbwindow);
// copy from the window device context to the bitmap device context
StretchBlt(hwindowCompatibleDC, 0, 0, width, height, hwindowDC, 0, 0, srcwidth, srcheight, SRCCOPY); //change SRCCOPY to NOTSRCCOPY for wacky colors !
GetDIBits(hwindowCompatibleDC, hbwindow, 0, height, src.u->data, (BITMAPINFO*)&bi, DIB_RGB_COLORS);  //copy from hwindowCompatibleDC to hbwindow

// avoid memory leak
DeleteObject(hbwindow ...
(more)
edit retag flag offensive close merge delete

Comments

1

i have no idea about using GPU but take a look at my class

sturkmen gravatar imagesturkmen ( 2020-10-20 15:54:09 -0500 )edit
1

this is simply impossible, using the win32 api, you'd have to rewrite the OS for it ...

maybe you could try with directX interop and acquire the front buffer, but this is all unchartered territory

berak gravatar imageberak ( 2020-10-21 02:03:33 -0500 )edit