想将Directshow采集到的视频保存成任意格式的图像保存出去,结合OPENCV的IplImage来实现;
下面是主要代码:
获取一帧媒体的数据
HRESULT hr;
AM_MEDIA_TYPE mediaType;
hr = pGrabber->GetConnectedMediaType(&mediaType);
if (FAILED(hr)) return hr;
VIDEOINFOHEADER *pVih;
if (mediaType.formattype == FORMAT_VideoInfo &&
(mediaType.cbFormat >= sizeof(VIDEOINFOHEADER)) &&
mediaType.pbFormat != NULL)
{
pVih = (VIDEOINFOHEADER *)mediaType.pbFormat;
}
else
return VFW_E_INVALIDMEDIATYPE;
if (SUCCEEDED(pGrabber->SetBufferSamples(TRUE)) ) // 设置为缓冲形式)
{
long cbBuffer = 0;
hr = pGrabber->GetCurrentBuffer(&cbBuffer, NULL);
BYTE *pBuffer = new BYTE[cbBuffer];
if (!pBuffer) return -1;
// 获取一帧媒体的数据
hr = pGrabber->GetCurrentBuffer(&cbBuffer, (long *)pBuffer);
if (FAILED(hr)) return hr;
//一帧媒体的数据 转成IplImage
IplImage *lko = cvCreateImageHeader(cvSize(frameSetW,frameSetH),IPL_DEPTH_8U,3);
cvSetData(lko,pBuffer,frameSetW*3);
cvFlip(lko);
char *filename2 = "Lena_New.jpg"; //图像名
cvSaveImage(filename2,lko);//把图像写入文件
///原本我是想转成GDI+中的CIMAGE格式的,但是没实现,下面的代码被我注释了。有空再来改吧
BYTE转成IStream流
//int nSize =m_BufferSize; //BYTE*指向的数据的长度
/* HGLOBAL hMem = GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_NODISCARD,cbBuffer);
IStream *pStream1 = NULL;
CreateStreamOnHGlobal(hMem,TRUE,&pStream1);
pStream1->Write(pBuffer,cbBuffer,NULL);
ULARGE_INTEGER pos;
LARGE_INTEGER iMove;
iMove.QuadPart = 0;
pStream1->Seek(iMove,STREAM_SEEK_SET,&pos);
///释放流对象资源
// pStream-> Release();
CImage m_new;
//m_new.Save(pStream1,Gdiplus::ImageFormatJPEG); //保存成JPEG IStream流
m_new.Load(pStream1);///加载IStream
m_new.Save("jj.jpg");
pStream1-> Release();
//释放可移动缓冲区资源
//GlobalFree(hMem);
if(m_new)
{
m_new.Destroy();
}*/
//delete pBuffer;
cvReleaseImageHeader(&lko);
delete pBuffer;
}
// pGrabber->SetOneShot(FALSE);
pGrabber->SetBufferSamples(FALSE);
FreeMediaType(mediaType);
return 0;