将RGB24样本保存到位图

时间:2012-04-17 13:08:16

标签: visual-c++ ms-media-foundation

我正在使用Windows Media Foundation来处理我的网络摄像头。我已经能够从网络摄像头成功检索数据样本,并确定格式为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.
 );

因此,一旦我使用IMFSample填充了pSample,我该如何将其保存为位图?

1 个答案:

答案 0 :(得分: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