windows mobile中使用DirectShow开发视频流之从摄像头流中捕捉一张图片

 

视频问题,从摄像头流中捕捉一张图片。用ISampleGrabber方法 (by Atomictry(天影))
关键字: 视频 捕获 拍照 ISampleGrabber

函 数说明

HRESULT StartDisplay(HWND hwnd);


HRESULT BuilderGraph()


HRESULT SnapStill()


BOOL SetFormat(ICaptureGraphBuilder2* pBuilder, IBaseFilter* pCap, long lWidth, long lHeight, unsigned short iColorBit, __int64 iRate )

HRESULT StartDisplay(HWND hwnd)
{
HRESULT hr = S_OK;
hr = BuilderGraph();
if(hr==S_FALSE) return S_FALSE;

//Create Display Windows
pSendWindow->put_Owner((OAHWND)hwnd);
pSendWindow->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
pSendWindow->SetWindowPosition(0,0,250,250);
pSendWindow->put_Visible(OATRUE);

hr = pGrabber->SetOneShot(FALSE);
hr = pGrabber->SetBufferSamples(TRUE);

//Begin display
hr=pSendControl->Run();
Sleep(500);
SnapStill();

return S_OK;
}

HRESULT BuilderGraph()
{
HRESULT hr=S_OK;

pSendGraph=NULL;
pCaputerFilter=NULL;
pCaputerBuilder=NULL;
pSendWindow=NULL;
pSendControl=NULL;
pSendEvent=NULL;
pGrabberSample = NULL;

//1.Builder Filter Graph
hr=CoCreateInstance((REFCLSID)CLSID_FilterGraph,NULL,
CLSCTX_INPROC_SERVER,
(REFIID)IID_IGraphBuilder,
(void**)&pSendGraph);
if(FAILED(hr)) return S_FALSE;

//2.Builder Caputer Filter
hr=CoCreateInstance(CLSID_CaptureGraphBuilder2,NULL,
CLSCTX_INPROC,IID_ICaptureGraphBuilder2,
(void**)&pCaputerBuilder);
if(FAILED(hr)) return S_FALSE;

//3.Builder SampleGrabber Filter
hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void**)&pGrabberSample);
if(FAILED(hr)) return S_FALSE;

hr=pCaputerBuilder->SetFiltergraph(pSendGraph);
if(FAILED(hr))return S_FALSE;

//Find Caputer Filter
hr=FindCaputerDevice();
if(FAILED(hr)) {
SAFE_RELEASE(pCaputerBuilder);
SAFE_RELEASE(pSendGraph);
return S_FALSE;
}

hr =pSendGraph->AddFilter(pNetSend,NULL);
hr =pSendGraph->AddFilter(pCaputerFilter,L"Caputer Filter");
hr =pSendGraph->AddFilter(pCompressor,L"Compressor Filter");
hr = pSendGraph->AddFilter(pGrabberSample, L"Sample Grabber");

hr=pSendGraph->QueryInterface(IID_IMediaControl,(void**)&pSendControl);
if(FAILED(hr)) return S_FALSE;

hr=pSendGraph->QueryInterface(IID_IVideoWindow,(void**)&pSendWindow);
if(FAILED(hr)) return S_FALSE;

hr=pSendGraph->QueryInterface(IID_IMediaEvent,(void**)&pSendEvent);
if(FAILED(hr)) return S_FALSE;

hr=pGrabberSample->QueryInterface(IID_ISampleGrabber, (void**)&pGrabber);
if(FAILED(hr)) return S_FALSE;

// 修改分辨率
SetFormat(pCaputerBuilder, pCaputerFilter, 640, 480, 24, 30);

//Display local video
hr=pCaputerBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,NULL,pCaputerFilter,pGrabberSample,NULL);
if(FAILED(hr)) return S_FALSE;

return S_OK;
}

HRESULT SnapStill()
{
HRESULT hr;

long cbBuffer = 0;
hr = pGrabber->GetCurrentBuffer(&cbBuffer, NULL);
if(FAILED(hr)) return E_FAIL;

char *pBuffer = new char[cbBuffer];
if (!pBuffer) {
// Deal Out of memory. Return an error code.
}
hr = pGrabber->GetCurrentBuffer(&cbBuffer, (long*)pBuffer);
if(FAILED(hr)) return E_FAIL;

//生成Bitmap
AM_MEDIA_TYPE mt;
hr = pGrabber->GetConnectedMediaType(&mt);
if (FAILED(hr)) return E_FAIL;

VIDEOINFOHEADER *pVideoHeader = (VIDEOINFOHEADER*)mt.pbFormat;
if(pVideoHeader==NULL) return E_FAIL;

BITMAPINFO BitmapInfo;
ZeroMemory(&BitmapInfo, sizeof(BitmapInfo));
CopyMemory(&BitmapInfo.bmiHeader, &(pVideoHeader->bmiHeader), sizeof(BITMAPINFOHEADER));

HBITMAP hBitmap;
hBitmap = ::CreateDIBitmap(::GetDC(NULL), &(pVideoHeader->bmiHeader), CBM_INIT, pBuffer, &BitmapInfo, DIB_RGB_COLORS);

if(hBitmap==NULL) return E_FAIL;
CString strSaveFileName="";
CFileDialog filedlg(FALSE,_T("bmp"),_T(""),OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,_T("BMP(*.bmp)"));
if(filedlg.DoModal()==IDOK){
strSaveFileName=filedlg.GetPathName();
SaveBitmapToFile(hBitmap,strSaveFileName.GetBuffer(0));
}

return hr;
}

BOOL SetFormat(ICaptureGraphBuilder2* pBuilder, IBaseFilter* pCap, long lWidth, long lHeight, unsigned short iColorBit, __int64 iRate )
{
VIDEOINFOHEADER* phead;
IAMStreamConfig* iconfig;

HRESULT hr;
hr = pBuilder -> FindInterface( &PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Interleaved,
pCap, IID_IAMStreamConfig, (void **)&iconfig );
if ( hr != NOERROR )
{
hr = pBuilder -> FindInterface( &PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, pCap,
IID_IAMStreamConfig, (void **)&iconfig);
}

if ( FAILED( hr ) )
return FALSE;

AM_MEDIA_TYPE* pmt;
if ( iconfig -> GetFormat( &pmt ) != S_OK )
return FALSE;

if ( pmt -> formattype == FORMAT_VideoInfo)
{
phead = ( VIDEOINFOHEADER* )pmt -> pbFormat;
phead -> bmiHeader.biBitCount = iColorBit;
phead -> bmiHeader.biWidth = lWidth;
phead -> bmiHeader.biHeight = lHeight;
phead -> bmiHeader.biSizeImage = lWidth * lHeight * iColorBit / 8;
phead -> AvgTimePerFrame = iRate;
if ( ( hr = iconfig -> SetFormat( pmt ) ) != S_OK )
return FALSE;
}
iconfig -> Release();
iconfig = NULL;
FreeMediaType( *pmt );
return TRUE;
}

摘自:http://blog.csdn.net/wmmly/category/660848.aspx

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值