16,472
社区成员
发帖
与我相关
我的任务
分享
void CFrameGrabberDlg::OnGrab()
{
HRESULT hr;
/*
// 定义IMediaDet接口实例
CComPtr< IMediaDet > pDet;
hr = CoCreateInstance( CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER,
IID_IMediaDet, (void**) &pDet );
// 将影片文件名转换成BSTR类型
CComBSTR openBSTR(m_editOpenDir);
// 设置IMediaDet接口的文件关联
hr = pDet->put_Filename(openBSTR);
pDet->get_FrameRate(&dRate);
pDet->get_StreamLength(&totaltime); // 获取整个视频的时间长度
pDet ->Release;
*/
hr = GrabFrameFromMovie();
if (hr != S_OK)
AfxMessageBox("无法抓取帧!");
else
AfxMessageBox("抓取成功!");
}
HRESULT CFrameGrabberDlg::GrabFrameFromMovie()
{
double dtime = 0.00;
double totaltime=1;
for (dtime =0;dtime<totaltime;dtime+=0.04)
{
HRESULT hr;
// 定义IMediaDet接口实例
CComPtr< IMediaDet > pDet;
hr = CoCreateInstance( CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER,
IID_IMediaDet, (void**) &pDet );
if (FAILED(hr))
return hr;
// 将影片文件名转换成BSTR类型
CComBSTR openBSTR(m_editOpenDir);
// 设置IMediaDet接口的文件关联
hr = pDet->put_Filename(openBSTR);
if (FAILED(hr))
return hr;
// 从影片中检索视频流和音频流
long lStreams;
hr = pDet->get_OutputStreams(&lStreams);
if (FAILED(hr))
return hr;
// 取出影片的视频流,因为帧的信息是保存在视频流中的
bool bFound = false;
//------ 1 ----------------------
for (int i=0; i<lStreams; i++)
{
GUID major_type;
hr = pDet->put_CurrentStream(i);
if (SUCCEEDED(hr))
hr = pDet->get_StreamType(&major_type);
if (FAILED(hr))
break;
//---------- 2 ---------------
if (major_type == MEDIATYPE_Video)
{
bFound =true;
long width = 0, height = 0; // 存储位图的宽和高(单位:象素)
AM_MEDIA_TYPE mt;
hr = pDet->get_StreamMediaType(&mt);
//----------- 3 -----------------------
if (SUCCEEDED(hr))
{
if ((mt.formattype == FORMAT_VideoInfo) &&
(mt.cbFormat >= sizeof(VIDEOINFOHEADER)))
{
// 得到VIDEOINFOHEADER结构指针,VIDEOINFOHEADER结构包含一些与视频
// 有关的信息,其中含有BITMAPINFORHEADER结构
VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)(mt.pbFormat);
width = pVih->bmiHeader.biWidth;
height = pVih->bmiHeader.biHeight;
}
else
hr = VFW_E_INVALIDMEDIATYPE;
MyFreeMediaType(mt); // 释放AM_MEDIA_TYPE结构
}
long size;
//double dtime = 0.00;
//double totaltime,dRate;
pDet->get_StreamLength(&totaltime); // 获取整个视频的时间长度
//pDet->get_FrameRate(&dRate);
CStatic * ps = (CStatic *)GetDlgItem(AFX_IDS_PICTYPE_BITMAP); //picture是CStatic类型
// 每1秒,截取视频截图
//for(dtime=0.0; dtime <totaltime; dtime+=0.4)
//{
// 获取bitmap的buffer大小
hr = pDet->GetBitmapBits(dtime, &size, 0, width, height);
if (SUCCEEDED(hr))
{
//分配缓冲区
char *pBuffer = new char[size];
if (!pBuffer)
return NULL;
//------------------ 4 ------------------------
hr = pDet->GetBitmapBits(dtime, 0, pBuffer, width, height);
if (SUCCEEDED(hr))
{
// Find the address of the start of the image data.
void *pData = pBuffer + sizeof(BITMAPINFOHEADER);
BITMAPINFOHEADER *bmih = (BITMAPINFOHEADER*)pBuffer;
BITMAPINFO bmi;
ZeroMemory(&bmi, sizeof(BITMAPINFO));
CopyMemory(&(bmi.bmiHeader), bmih, sizeof(BITMAPINFOHEADER));
HBITMAP hBitmap = CreateDIBitmap(::GetDC(NULL), bmih, CBM_INIT,
pData, &bmi, DIB_RGB_COLORS);
ps->SetBitmap(hBitmap);
DeleteObject(hBitmap);
//ps->ReleaseDC;
}
delete[] pBuffer;
}
//::Sleep(400);
//}
}
}
pDet ->Release;
::Sleep(40);
if (!bFound)
return VFW_E_INVALIDMEDIATYPE;
if (FAILED(hr))
return hr;
}
return S_OK;
}