通过IBasicVideo::GetCurrentImage接口 对于该接口,Video Renderer和Video Mixing Renderer(VMR)有不同的实现。 A)Video Renderer 如果该Renderer使用了DDraw加速的话,该调用会失败。在调用该接口的时候,必须首先暂停Renderer(可以通过IMediaControl::Pause()暂停,如果不能确信该操作是否成功,应该调用IMediaControl::GetState()判断状态)。 B)Video Mixing Renderer 对于VMR,该方法都会成功(不管是否运用了DDraw加速,也不管是否是暂停状态),此时对于它所有的状态(running, stopped, or paused)都适用。 函数Grabber代码如下(调用该函数的时候应该先将媒体文件暂停,原因上面已经说了): #001 bool Grabber(IBasicVideo mBasicVideo, TCHAR *szFilename) #002 { #003 if (mBasicVideo) #004 { #005 long bitmapSize = 0; #006 if(SUCCEEDED(mBasicVideo->GetCurrentImage(&bitmapSize, 0))) #007 { #008 //if语句里面的操作时取得buffer的size。 #009 //当我们在布确定image buffer的大小的情况下,我们给 #010 //GetCurrentImage的第二个参数传递0或者NULL,取得buffer的 #011 //大小供以后使用。 #012 bool pass = false; #013 unsigned char * buffer = new unsigned char[bitmapSize]; #014 if(SUCCEEDED(mBasicVideo->GetCurrentImage(&bitmapSize,(long*)buffer))) #015 { #016 //此时已经用到刚才所取得的大小(分配空间) #017 BITMAPFILEHEADER hdr; //Bitmap的头信息 #018 LPBITMAPINFOHEADER lpbi; // Bitmap的文件信息(包括数据) #019 #020 lpbi = (LPBITMAPINFOHEADER)buffer; #021 #022 int nColors = 1 << lpbi->biBitCount; #023 if (nColors > 256) #024 nColors = 0; #025 #026 hdr.bfType = ((WORD) ('M' << 8) | 'B'); //always is "BM" #027 hdr.bfSize = bitmapSize + sizeof( hdr ); #028 hdr.bfReserved1 = 0; #029 hdr.bfReserved2 = 0; #030 hdr.bfOffBits = (DWORD) (sizeof(BITMAPFILEHEADER) + lpbi->biSize #031 CFile bitmapFile(outFile, CFile::modeReadWrite | CFile::modeCreate | CFile::typeBinary); #032 bitmapFile.Write(&hdr, sizeof(BITMAPFILEHEADER)); #033 bitmapFile.Write(buffer, bitmapSize); #034 bitmapFile.Close(); #035 pass = true; #036 } #037 delete [] buffer; //数据用过之后记得要释放空间 #038 return true; #039 } #040 } #041 #042 return false; #043 } IMediaDet接口 IMediaDet接口可以取得媒体文件的信息。SDK里面的示例代码(没有写入文件): #001 long size; #002 //取得图像帧的大小,给GetBitmapBits的第三个参数传递0 or NULL #003 hr = pDet->GetBitmapBits(0, &size, 0, width, height); #004 if(SUCCEEDED(hr)) #005 { #006 char *pBuffer = new char[size]; #007 if(!pBuffer) #008 { #009 return E_OUTOFMEMORY; #010 } #011 #012 try #013 { #014 hr = pDet->GetbitmapsBits(0, 0, pBuffer, width, height); #015 } #016 catch(...) #017 { #018 delete [] pBuffer; #019 throw; #020 } #021 #022 if(SUCCEEDED(hr)) #023 { #024 BITMAPINFOHEADER *bmih = (BITMAPINFOHEADER*)pBuffer; #025 HDC hdcDest = GetDC(0); #026 #027 //Find the address of the start of the image data #028 void *pData = pBuffer + sizeof(BITMAPINFOHEADER); #029 #030 //Note: In general a BITMAPINFOHEADER can include extra color #031 //information at the end, so calculating the offset to the image #032 //data i snot generally correct. However, the IMediaDet interface #033 //always returns an RGB-24 image with no extra color information #034 #035 BITMAPINFO bmi; #036 ZeroMemory(&bmi, sizeof(BITMAPINFO)); #037 CopyMemory(&(bmi.bmiHeader), bmih, sizeof(BITMAPINFOHEADER)); #038 HBITMAP hBitmap = CreateDIBitmap(hdcDect, bmih, CBM_INIT, #039 pData, &bmi, DIB_RGB_COLORS); #040 } #041 #042 delete [] pBuffer; #043 } 该方法并没有写入bitmap,具体的写入过程可以参加上面的几种方法。
|