2016-01-28 48 views
2

我试图用GDI截图,然后我在FFmpeg中使用它。 屏幕截图效果很好,FFmpeg处理它没有任何问题。GDI截图,结果在不同的计算机上变化

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

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激活...)。 我不明白,因为我的代码按照我发现的所有例子...

请帮帮我!

+1

寻找我就像你只是用rgb而不是rgba。 (只是我想到的第一件事) – AntiHeadshot

+0

对,我只使用rgb频道,但我明白的是通过设置biClrUsed为24,BitBlt将rgba转换为rgb。此外,在我的电脑上DC返回32位,但图像是好的,我没有这个问题。 – Maypeur

+0

你如何计算'mWxHxS'值? –

回答

1

所以我finaly找到解决方案:

看来,BitBlt和StretchBlt函数并不真正正确处理的某些计算机上32到24位之间的传输...

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

我的变化:

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; 
    } 

感谢试图帮助我!

3

您正在创建设备无关位图(CreateDIBSection),然后使用Device Dependent Context(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

+0

谢谢马特,我明白现在有什么问题,但我想从设备上下文复制到DIB和StrechDIBits似乎做倒置(从DIB到矩形) 我对吗 ?在你的链接的例子保存一个兼容的DC像我的代码...所以我想我需要找到一个上下文独立的HDC DIB功能! – Maypeur

+0

我尝试使用CreateCompatible位图并使用GetDIBits,但总是得到相同的结果:'hBitmap = CreateCompatibleBitmap(hScreenDC,mWidth,mHeight); if(GetDIBits(hScreenDC,hBitmap,0,mHeight,mImageBuffer,&bi,DIB_RGB_COLORS))' – Maypeur

相关问题