GDI截图,结果因计算机而异

时间:2016-01-28 09:24:08

标签: c++ windows bitmap screenshot gdi

我尝试用GDI截取屏幕截图,然后在FFmpeg中使用它。 截图效果很好,FFmpeg处理它没有任何问题。

但是,在某些计算机上,图像不是我想要的,就像你在下面看到的那样。

enter image description here

这是我用来初始化我的位图的代码:

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

这里有每个截图:

if(BitBlt(
    hMemoryDC,
    0,
    0,
    mWidth,
    mHeight,
    hScreenDC,
    mPx,
    mPy,
    SRCCOPY | CAPTUREBLT
))

运行我的应用程序时没有任何错误,但这个丑陋的图像只在某些计算机上运行。 我不知道在这些电脑上有什么不同(所有都是Win7,Aero有效......)。 我不明白,因为我的代码遵循我发现的所有例子......

请帮助我!

2 个答案:

答案 0 :(得分:3)

您正在创建与设备无关的位图(CreateDIBSection),然后使用设备相关上下文(CreateCompatibleDC)来处理它。我相信你需要创建一个与设备相关的位图以与BitBlt兼容,或者使用StretchDIBits来支持与设备无关的图像数据。这在某些计算机而非其他计算机上工作的原因是因为视频驱动程序确定了设备相关图像的格式,这可能与Windows设备无关图像的定义相同或不同。

以下是捕获图像的示例(是的,它不必要地长,但似乎仍然包含良好的信息):https://msdn.microsoft.com/en-us/library/windows/desktop/dd183402(v=vs.85).aspx

以下是关于StretchDIBits的文档,以防您需要DIB:https://msdn.microsoft.com/en-us/library/windows/desktop/dd145121(v=vs.85).aspx

答案 1 :(得分:1)

所以我最终找到了解决方案:

似乎BitBlt和StretchBlt并没有真正正确处理某些计算机上32到24位之间的传输......

现在,我只使用32位GDI,让FFmpeg和libswscale将我的RGBA图像转换为YUV格式。

我的更改:

dict

感谢您帮助我!