I tried capturing a part of the screen and put it in a cv::Mat
, the output is the same color (when i captured a white background it is white, when gray it is gray so you can understand it does function to some degree) but the image is fuzzy, aligned and repetitive (it repeats the same pixels).
For example, upon writing this question in my Chrome browser I tried the program and the result was:
You can recognize the browser (the URL-bar, the text box and buttons and so on. But the image itself is far from accurate or even close, and the pixels are repetitive when they shouldn't be (url bar repeats itself, text box and so on).
The code in this question did not compile on my machine. But I know that the code I used (not the OpenCV part) works on my machine (I already used it to capture my screen and it worked perfectly when I saved it with libpng
).
My code is as follows (the variables which aren't declared here are declared elsewhere and which value is correct, i checked, such as x
, w
, h
etc.):
HDC hdcSource = GetDC(NULL);
HDC hdcMemory = CreateCompatibleDC(hdcSource);
HBITMAP hBitmap = CreateCompatibleBitmap(hdcSource, w, h);
HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMemory, hBitmap);
BITMAPINFOHEADER bmi = { 0 };
bmi.biSize = sizeof(BITMAPINFOHEADER);
bmi.biPlanes = 1;
bmi.biBitCount = 24;
bmi.biWidth = w;
bmi.biHeight = -h;
bmi.biCompression = BI_RGB;
bmi.biSizeImage = ((bmi.biWidth * bmi.biBitCount + 31) & ~31) / 8 * bmi.biHeight<0 ? -bmi.biHeight : bmi.biHeight;
bmi.biXPelsPerMeter = 0;
bmi.biYPelsPerMeter = 0;
bmi.biClrImportant = 0;
bmi.biClrUsed = 256;
if (!(BitBlt(hdcMemory, 0, 0, w, h, hdcSource, p1.x, p1.y, SRCCOPY)))
{
exit(1);
}
hBitmap = (HBITMAP)SelectObject(hdcMemory, hBitmapOld);
if (!hBitmap)
{
exit(1);
}
my_pic.create(h, w, CV_8UC4);
//StretchBlt(hdcSource, 0, 0, w, h, GetDC(NULL), 0, 0, w, h, SRCCOPY); //This line is what I saw in the other question but it didn't help
if (!(GetDIBits(hdcSource, hBitmap, 0, h, my_pic.data, (BITMAPINFO*)&bmi, DIB_RGB_COLORS)))
{
exit(1);
}
DeleteDC(hdcSource);
DeleteDC(hdcMemory);