Reputation: 396
I try to take a screenshot with GDI, then i use it in FFmpeg. The screenshot works well and FFmpeg handle it without any problem.
But, on some computer, the image is not very what i want like you can see below.
Here is the code i use to init my bitmap :
//--
mImageBuffer = new unsigned char[mWxHxS];
memset(mImageBuffer, 0, mWxHxS);
//--
hScreenDC = GetDC(0);
hMemoryDC = CreateCompatibleDC(hScreenDC);
//--
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biBitCount = 24;
bi.bmiHeader.biWidth = mWidth;
bi.bmiHeader.biHeight = mHeight;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biClrUsed = 24;
bi.bmiHeader.biClrImportant = 256;
hBitmap = CreateDIBSection(hMemoryDC, &bi, DIB_RGB_COLORS, &mImageBuffer, 0, 0);
SelectObject(hMemoryDC, hBitmap);
And here for each screenshot :
if(BitBlt(
hMemoryDC,
0,
0,
mWidth,
mHeight,
hScreenDC,
mPx,
mPy,
SRCCOPY | CAPTUREBLT
))
I do not have any error running my application but this ugly image and only on some computer. I don't know what is the difference causing that on these computer (All are Win7, Aero actived...). I do not understand because my code follow all example i found...
Please help me !
Upvotes: 3
Views: 465
Reputation: 396
So i finaly find the solution :
It seems that the BitBlt and StretchBlt doesnt really handle correctly the transfer between 32 to 24 bits on some computers...
Now, i use only 32bits with GDI and let FFmpeg with libswscale convert my RGBA image to a YUV format.
My changes :
mWidth = GetDeviceCaps(hScreenDC, HORZRES);
mHeight = GetDeviceCaps(hScreenDC, VERTRES);
mWxHxS = mWidth*mHeight*4;
bi.bmiHeader.biBitCount = 32;
hBitmap = CreateCompatibleBitmap(hScreenDC, mWidth, mHeight);
if(BitBlt(
hMemoryDC,
0,
0,
mWidth,
mHeight,
hScreenDC,
mPx,
mPy,
SRCCOPY | CAPTUREBLT
) && GetDIBits(hScreenDC, hBitmap, 0, mHeight, mImageBuffer, &bi, DIB_RGB_COLORS))
{
return true;
}
Thanks trying to help me !
Upvotes: 1
Reputation: 2181
You are creating a Device-Independent-Bitmap (CreateDIBSection) then using a Device Dependent Context (CreateCompatibleDC) to work with it. I believe you need to create a device dependent bitmap to be compatible with BitBlt, or use StretchDIBits to support device-independent image data. The reason this works on some computers and not others is because the video driver determines the format of a device-dependent image, which may or may not be the same as the Windows definition of a device-independent image.
Here is an example of capturing an image (yes, its unnecessarily long, but still seems to contain good info): https://msdn.microsoft.com/en-us/library/windows/desktop/dd183402(v=vs.85).aspx
And here is documentation on StretchDIBits, in case you require a DIB: https://msdn.microsoft.com/en-us/library/windows/desktop/dd145121(v=vs.85).aspx
Upvotes: 3