[转] 从摄像头流中捕捉一张图片
2010-02-08 17:06
288 查看
视频问题,从摄像头流中捕捉一张图片。用ISampleGrabber方法 (by Atomictry(天影))
//函数说明 /* * 本地显示函数 */ 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; }
相关文章推荐
- DirectShow:图片的抓取---从摄像头流中捕捉一张图片zzDirectshow中的视频捕捉
- windows mobile中使用DirectShow开发视频流之从摄像头流中捕捉一张图片
- DirectShow:图片的抓取 zz从摄像头流中捕捉一张图片zzDirectshow中的视频捕捉zz
- WPF利用MediaFoundation打开摄像头捕捉图片
- ffmpeg从USB摄像头采集一张原始图片
- 利用ov511的webeye v2000摄像头实现YUV420P格式转RGB24格式来抓取一张图片
- 利用ov511的webeye v2000摄像头实现YUV420P格式转RGB24格式来抓取一张图片
- V4L2编程使用USB摄像头生成一张图片
- 利用ov511的webeye v2000摄像头实现YUV420P格式转RGB24格式来抓取一张图片
- ffmpeg从USB摄像头采集一张原始图片(转)
- 利用ov511的webeye v2000摄像头实现YUV420P格式转RGB24格式来抓取一张图片
- 制作一张任意像素的全透明图片
- iOS开发小方法:根据UIColor一个颜色生成一张图片
- jquery实现多次上传同一张图片
- ios中摄像头/相册获取图片,压缩图片,上传服务器方法
- 一张图片,让你彻底清除线程的生命周期
- C#上传图片 并按尺寸新生成一张略缩图
- jsp页面实现点击一张图片,然后就全屏放大,再点击,图片会恢复原状
- 还有一张图片
- 关于EMGU CV的那些事——2.摄像头捕捉(RGB and GRAY)