2012-04-17 63 views
1

我正在使用Windows Media Foundation對我的攝像頭進行一些修改。我已經能夠成功從網絡攝像頭獲取數據樣本,並確定格式爲RGB24。現在我想將一個幀保存爲位圖。下面是我用來從網絡攝像頭讀取樣本的一小段代碼。將RGB24示例保存到位圖

IMFSample *pSample = NULL; 

hr = pReader->ReadSample(
    MF_SOURCE_READER_ANY_STREAM, // Stream index. 
    0,        // Flags. 
    &streamIndex,     // Receives the actual stream index. 
    &flags,       // Receives status flags. 
    &llTimeStamp,     // Receives the time stamp. 
    &pSample      // Receives the sample or NULL. 
); 

所以一旦我有pSample填充一個IMFSample我怎樣才能將它保存爲位圖?

+1

使用IMFSample :: ConvertToContinguousBuffer()獲取IMFMediaBuffer接口指針。 QI它爲IMF2DBuffer。然後使用其Lock2D()方法獲取指向像素數據的指針。 – 2012-04-17 13:41:40

+0

我現在可以得到那麼多。關於如何將IMF2DBuffer保存到位圖文件的任何指針?我在四處搜尋,但還沒有找到解決方案。 – sipwiz 2012-04-18 10:47:17

+0

無論我設法把東西湊在一起。在刪除一些錯誤之後,我會將我的代碼示例作爲答案發布。 – sipwiz 2012-04-18 12:52:52

回答

1

下面是我用來從IMFSample保存位圖的代碼片段。我已經採取了很多快捷方式,我敢肯定,我只能以這種方式逃避,因爲我的網絡攝像機默認返回一個RGB24流,並且還有一個640 x 480像素的緩衝區,這意味着沒有條紋擔心pData。

hr = pReader->ReadSample(
    MF_SOURCE_READER_ANY_STREAM, // Stream index. 
    0,        // Flags. 
    &streamIndex,     // Receives the actual stream index. 
    &flags,       // Receives status flags. 
    &llTimeStamp,     // Receives the time stamp. 
    &pSample      // Receives the sample or NULL. 
    ); 

wprintf(L"Stream %d (%I64d)\n", streamIndex, llTimeStamp); 

HANDLE file; 
BITMAPFILEHEADER fileHeader; 
BITMAPINFOHEADER fileInfo; 
DWORD write = 0; 

file = CreateFile(L"sample.bmp",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); //Sets up the new bmp to be written to 

fileHeader.bfType = 19778;                 //Sets our type to BM or bmp 
fileHeader.bfSize = sizeof(fileHeader.bfOffBits) + sizeof(RGBTRIPLE);            //Sets the size equal to the size of the header struct 
fileHeader.bfReserved1 = 0;                 //sets the reserves to 0 
fileHeader.bfReserved2 = 0; 
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);     //Sets offbits equal to the size of file and info header 

fileInfo.biSize = sizeof(BITMAPINFOHEADER); 
fileInfo.biWidth = 640; 
fileInfo.biHeight = 480; 
fileInfo.biPlanes = 1; 
fileInfo.biBitCount = 24; 
fileInfo.biCompression = BI_RGB; 
fileInfo.biSizeImage = 640 * 480 * (24/8); 
fileInfo.biXPelsPerMeter = 2400; 
fileInfo.biYPelsPerMeter = 2400; 
fileInfo.biClrImportant = 0; 
fileInfo.biClrUsed = 0; 

WriteFile(file,&fileHeader,sizeof(fileHeader),&write,NULL); 
WriteFile(file,&fileInfo,sizeof(fileInfo),&write,NULL); 

IMFMediaBuffer *mediaBuffer = NULL; 
    BYTE *pData = NULL; 

pSample->ConvertToContiguousBuffer(&mediaBuffer); 

hr = mediaBuffer->Lock(&pData, NULL, NULL); 

WriteFile(file, pData, fileInfo.biSizeImage, &write, NULL); 

CloseHandle(file); 

mediaBuffer->Unlock(); 

我已經加入了一些討論here

+0

是否需要位圖文件標頭?我可以簡單地將RGB24數據保存到位圖文件嗎? – 2014-11-24 15:04:44

+0

我敢肯定,你需要頭文件被其他應用程序識別,否則它將只是原始像素數據,並且不可能知道行和列開始的位置。 – sipwiz 2014-11-24 21:17:44