2016-01-28 86 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

相關問題