VC捕捉攝像頭圖像入門(mén)源碼要點(diǎn)
《VC捕捉攝像頭圖像入門(mén)源碼要點(diǎn)》由會(huì)員分享,可在線(xiàn)閱讀,更多相關(guān)《VC捕捉攝像頭圖像入門(mén)源碼要點(diǎn)(16頁(yè)珍藏版)》請(qǐng)?jiān)谘b配圖網(wǎng)上搜索。
1、 【轉(zhuǎn)】VC捕捉攝像頭圖像入門(mén)源碼 VC捕捉攝像頭圖像入門(mén)源碼(非常適合新手)(轉(zhuǎn)) 默認(rèn)分類(lèi)2009-11-02 17:46:56 閱讀39評(píng)論0字號(hào):大中 小 〃此源碼是我更改過(guò)的基于 VFW(Video for Windows)的源碼,使用了定時(shí)器能 實(shí)時(shí)的顯示圖像,從網(wǎng)上可搜到原版源碼,但是原版的功能是保存為一個(gè)文件, 且不能實(shí)時(shí)顯示,此版本雖然能顯示,但感覺(jué)反應(yīng)速度不是很快,沒(méi)有基于 DirectShow的程序更新速度快,不過(guò)在 WM_PAINT息處理里加 while(1){capGrabFrame(ghWndCap);}刷新速度就快很多了,但是這樣程序就進(jìn) 入死循環(huán)不
2、能再處理其他消息,至于怎樣改進(jìn),就靠讀者你了。
//源碼的任何部分都可以在 MSDN!查至IJ,請(qǐng)參考 MSDN
#include
3、"CamCapture.AVI"; ///////////////////////////////////////////////////////////////////// // // StatusCallbackProc: 冊(cè)這個(gè)回調(diào)函數(shù)。 // hWnd: // nID: // lpStatusText: 狀態(tài)回調(diào)函數(shù),使用capSetCallbackOnStatus 宏來(lái)注 捕獲窗體句柄 當(dāng)前狀態(tài)的狀態(tài)碼 當(dāng)前狀態(tài)的文本字符 /////////////////////////////////////////////////////////////////////
4、 // LRESULT CALLBACK StatusCallbackProc(HWND hWnd,int nID,LPSTR lpStatusText) { if(!ghWndCap) return FALSE;// 獲得捕獲窗的狀態(tài) capGetStatus(ghWndCap,&gCapStatus,sizeof(CAPSTATUS));// 更新捕獲窗的大 小 , 得到消息 WM_CAP_GET_STATUS SetWindowPos(ghWndCap,NULL,0,0,gCapStatus.uiImageWidth,gCapStatus.uiI mageHeight,S
5、WP_NOZORDER|SWP_NOMOVE); if(nID==0){// 清除舊的狀態(tài)信息 SetWindowText(ghWndCap,(LPSTR)"hello"); return (LRESULT)TRUE; }// 顯示狀態(tài) ID 和狀態(tài)文本 wsprintf(gachBuffer,"Status# %d: %s",nID,lpStatusText); SetWindowText(ghWndCap,(LPSTR)gachBuffer); return (LRESULT)TRUE; } ////////////////////////////////////////
6、///////////////////////////// ///////// // ErrorCallbackProc: 錯(cuò)誤回調(diào)函數(shù) , 過(guò) capSetCallbackOnError 宏來(lái) 注冊(cè)回調(diào) 捕獲窗口句柄 錯(cuò)誤代碼 關(guān)于錯(cuò)誤的文本信息 // hWnd: // nErrID: // lpErrorText: ///////////////////////////////////////////////////////////////////// ////////// LRESULT CALLBACK ErrorCallbackProc(HWND hWnd,int
7、nErrID,LPSTR lpErrorText) { if(!ghWndCap) return FALSE; if(nErrID==0) return TRUE;// 清除舊的錯(cuò)誤 wsprintf(gachBuffer,"Error# %d",nErrID);// 顯示錯(cuò)誤標(biāo)識(shí)和文本 MessageBox(hWnd, lpErrorText, gachBuffer,MB_OK | MB_ICONEXCLAMATION); return (LRESULT) TRUE; } ///////////////////////////////////////////////////
8、////////////////// ///////// // FrameCallbackProc: 幀回調(diào)函數(shù) , 通過(guò) capSetCallbackFrame 宏來(lái)注冊(cè) 捕獲窗體句柄 指向一個(gè)包含幀信息的數(shù)據(jù)結(jié)構(gòu)體 回調(diào)函數(shù) // hWnd: // lpVHdr: ///////////////////////////////////////////////////////////////////// //////////// LRESULT CALLBACK FrameCallbackProc(HWND hWnd,LPVIDEOHDR lpVHdr) { FILE *f
9、p; fp=fopen("caram.dat","w"); if(!ghWndCap) return FALSE;// 假設(shè) fp 為一打開(kāi)的 .dat 文件指針 fwrite(lpVHdr->lpData,1,lpVHdr->dwBufferLength,fp); return (LRESULT)TRUE; } ///////////////////////////////////////////////////////////////////// ///////// //TimerProc 函數(shù)處理定時(shí)器,在這里抓取并顯示圖像 ///////////////////////
10、////////////////////////////////////////////// ///////// VOID CALLBACK TimerProc( HWND hwnd, // handle to window UINT uMsg, // WM_TIMER message UINT_PTR idEvent, // timer identifier DWORD dwTime // current system time ) { capGrabFrame(ghWndCap); } /////////////////////////////////////////
11、///////////////////////// // 主回調(diào)函數(shù) ////////////////////////////////////////////////////////////////// LRESULT CALLBACK WindowProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { // HDC hd
12、c; // PAINTSTRUCT ps; // RECT rect; switch(uMsg) { case WM_CREATE: ghWndCap=capCreateCaptureWindow((LPSTR)"Capture Window",WS_CHILD|WS_VISIBLE,0,0,320,240,(HWND)hwnd,(int)0); capSetCallbackOnError(ghWndCap,(FARPROC)ErrorCallbackProc); capSetCallbackOnStatus(ghWndCap,(FARPROC)StatusCallbackPr
13、oc); capSetCallbackOnFrame(ghWndCap,(FARPROC)FrameCallbackProc); capDriverConnect(ghWndCap,0); // 將捕獲窗同驅(qū)動(dòng)連接 capDriverGetCaps(ghWndCap,&gCapDriverCaps,sizeof(CAPDRIVERCAPS)) ;// 獲得驅(qū)動(dòng)的能力 , 相關(guān)的信息放在結(jié)構(gòu)變量 gCapDriverCaps 中 capPreviewRate(ghWndCap, 66); //uses this macro to set the frame display rate f
14、or preview mode to 66 milliseconds per frame capPreview(ghWndCap, TRUE); //and then uses the capPreview macro to place the capture window in preview mode. if(gCapDriverCaps.fHasOverlay) // 檢查驅(qū)動(dòng)器是否有疊加能力 capOverlay(ghWndCap,TRUE); // 啟動(dòng) Overlay 模式 if(gCapDriverCaps.fHasDlgVideoSource)capDlgVideoSo
15、urce(ghWndCap); //Video source 對(duì)話(huà)框 if(gCapDriverCaps.fHasDlgVideoFormat)capDlgVideoFormat(ghWndCap); // Video format 對(duì)話(huà)框 if(gCapDriverCaps.fHasDlgVideoDisplay)capDlgVideoDisplay(ghWndCa p); // Video display 對(duì)話(huà)框 // capFileSetCaptureFile( ghWndCap,szCaptureFile); // 將要保存的文 件名設(shè)為本源文件開(kāi)頭處的全局字符串常量
16、// capFileAlloc(ghWndCap, (1024L * 1024L * 5)); // 為捕獲文件分配存 儲(chǔ)空間 capCaptureSequence(ghWndCap); // 開(kāi)始捕獲視頻序列 // capGrabFrame(ghWndCap); // 捕獲單幀圖像 SetTimer(hwnd,1,10,TimerProc); break; case WM_PAINT: capGrabFrame(ghWndCap); /* hdc=BeginPaint(hwnd,&ps); GetClientRect(hwnd,&rect); DrawText(hdc,T
17、EXT("Hello,Windows XP!"),-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER); EndPaint(hwnd,&ps);*/ break; case WM_CLOSE: if(IDYES==MessageBox(hwnd,"Sure exit ?","CamCapture",MB_YESNO)) { DestroyWindow(hwnd); } break; case WM_DESTROY: KillTimer(hwnd,1); capSetCallbackOnStatus(ghWndCap,NULL); capSe
18、tCallbackOnError(ghWndCap,NULL); capSetCallbackOnFrame(ghWndCap,NULL); capCaptureAbort(ghWndCap);// 停止捕獲 capDriverDisconnect(ghWndCap); // 將捕獲窗同驅(qū)動(dòng)斷開(kāi) PostQuitMessage(0); break; default: return DefWindowProc(hwnd,uMsg,wParam,lParam); } return 0; } // 主函數(shù) int WINAPI WinMain( HINSTANCE hInstance,
19、 // handle to current instance HINSTANCE hPrevInstance, // handle to previous instance LPSTR lpCmdLine, // command line int nCmdShow // show state ) { static TCHAR szAppName[]=TEXT("CamCapture"); WNDCLASS wndcls; HWND hwnd; MSG msg; wndcls.cbClsExtra=0; wndcls.cbWndExtra=0; wndcls.hbrBackgro
20、und=(HBRUSH)GetStockObject(BLACK_BRUSH); wndcls.hCursor=LoadCursor(NULL,IDC_CROSS); wndcls.hIcon=LoadIcon(NULL,IDI_QUESTION); wndcls.hInstance=hInstance; wndcls.lpfnWndProc=WindowProc; wndcls.lpszClassName="CamCapture"; wndcls.lpszMenuName=NULL; wndcls.style=CS_HREDRAW | CS_VREDRAW; if(!Registe
21、rClass(&wndcls)) { MessageBox(NULL,TEXT("This program requires Windows NT!"),szAppName,MB_ICONERROR); return 0; } hwnd=CreateWindow("CamCapture","CamCapture",WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,320,240,NULL,NULL,hInstance,NULL); ShowWindow(hwnd,nCmdShow); UpdateWindow(hwnd); whi
22、le(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } 摘要: 本文主要講述用 Directshow 進(jìn)行視頻捕捉 (捕捉靜態(tài)圖像) 的編程思路, 并提供針對(duì)攝像頭編程的一個(gè)視頻捕捉類(lèi) CcaptureVideo 和一個(gè)示例。 、戶(hù) 、. 前言 DirectShow是微軟公司提供的一套在 Windows平臺(tái)上進(jìn)行流媒體處理的開(kāi) 發(fā)包,與 DirectX 開(kāi)發(fā)包一起發(fā)布。 DirectShow 為多媒體流的捕捉和回放提供 了強(qiáng)有力的支持。用
23、DirectShow 開(kāi)發(fā)應(yīng)用程序,我們可以很方便地從支持 WDM 驅(qū)動(dòng)模型的采集卡上捕獲數(shù)據(jù),并且進(jìn)行相應(yīng)的后期處理乃至存儲(chǔ)到文件中。 DirectShow是基于COM勺,為了編寫(xiě) DirectShow應(yīng)用程序,需要了解 COM 客戶(hù)程序編寫(xiě)的基礎(chǔ)知識(shí)。 DirectShow 提供了大量的接口,但在編程中發(fā)現(xiàn)還 是不夠方便, 如果能構(gòu)建一個(gè)視頻捕捉類(lèi)把常用的一些動(dòng)作封裝起來(lái), 那么就更 方便了。 編程思路 為了更加容易建立視頻捕捉應(yīng)用程序, DirectShow 提供了一個(gè)叫做 Capture Graph Builder 的對(duì)象, Capture Graph Builder
24、提供 IcaptureGraphBuilder2 接口,該接口可以建立和控制 Capture Graph 。 建立視頻捕捉程序,必須首先獲取并初始化 IcaptureGraphBuilder2 接口, 然后選擇一個(gè)適當(dāng)?shù)囊曨l捕捉設(shè)備。選擇好設(shè)備后,為該設(shè)備創(chuàng)建 Capture filter ,然后調(diào)用 AddFilter 把 Capture filter 添加到 Filter Graph 。 如果僅僅希望用攝像頭來(lái)進(jìn)行實(shí)時(shí)監(jiān)控的話(huà),只需要在上面的基礎(chǔ)上調(diào)用 ICaptureGraphBuilder2::RenderStream 就可以了: ICaptureGraphBuilder2
25、 *pBuild; // Capture Graph Builder // 省略初始化部分代碼 IBaseFilter *pCap; // Video capture filter. // 省略初始化和添加到 Filter Graph 部分代碼 pBuild->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap, NULL, NULL); DirectShow 提供了一個(gè)捕捉靜態(tài)圖像的方法: 使用 SampleGrabber filter 。 依次按照以下三個(gè)步驟就可以了: 第一步 , 定義一個(gè)類(lèi)實(shí)現(xiàn) Sample
26、 Grabber 的回調(diào)接口 IsampleGrabberCB : class CSampleGrabberCB : public ISampleGrabberCB { // 在后面提供的類(lèi)中具體完成 } CSampleGrabberCB mCB; 第二步、調(diào)用 RenderStream 依次把 Still pin 、 Sample Grabber 和系統(tǒng)默 認(rèn) Renderer Filter 連接起來(lái)。 第三步、配置 Sample Grabber 以捕獲數(shù)據(jù)。 視頻捕捉類(lèi) CCaptureVideo 的具體實(shí)現(xiàn) // CCaptureVideo 視頻捕捉類(lèi)頭文件 /////
27、//////////////////////////////////////////////////////////////// #if !defined(AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0 __INCLUDED_) #define AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0__INCLUDED_ ///////////////////////////////////////////////////////////////////// //
28、 CaptureVideo.h : header file
/////////////////////////////////////////////////////////////////////
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include
29、 \ x->Release( ); \ x = NULL; \ } #endif class CSampleGrabberCB; class CCaptureVideo : public CWnd { friend class CSampleGrabberCB; public: void GrabOneFrame(BOOL bGrab); HRESULT Init(int iDeviceID,HWND hWnd); int EnumDevices(HWND hList); CCaptureVideo(); virtual ~CCaptureVideo(); pri
30、vate:
HWND m_hWnd;
IGraphBuilder *m_pGB;
ICaptureGraphBuilder2* m_pCapture;
IBaseFilter* m_pBF;
IMediaControl* m_pMC;
IVideoWindow* m_pVW;
CComPtr
31、eVideoWindow(); HRESULT SetupVideoWindow(); HRESULT InitCaptureGraphBuilder(); }; #endif // !defined(AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0_ _INCLUDED_) // // CCaptureVideo 視頻捕捉類(lèi)實(shí)現(xiàn)文件 CaptureVideo.cpp // // CaptureVideo.cpp: implementation of the CCaptureVideo class. //
32、 ///////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "CaptureVideo.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif BOOL bOneShot=FALSE;/全局變量 class CSampleGrabberCB : public ISampleGrabberCB {
33、public: long lWidth; long lHeight; TCHAR m_szFileName[MAX_PATH];〃位圖文件名稱(chēng) CSampleGrabberCB( ){ strcpy(m_szFileName, "c:\\donaldo.bmp"); } STDMETHODIMP_(ULONG) AddRef() { return 2; } STDMETHODIMP_(ULONG) Release() { return 1; } STDMETHODIMP QueryInterface(REFIID riid, void ** ppv){ if( riid =
34、= IID_ISampleGrabberCB || riid == IID_IUnknown ){
*ppv = (void *) static_cast
35、ng lBufferSize ){ if( !bOneShot )return 0; if (!pBuffer)return E_POINTER; SaveBitmap(pBuffer, lBufferSize); bOneShot = FALSE; return 0; } // 創(chuàng)建位圖文件 BOOL SaveBitmap(BYTE * pBuffer, long lBufferSize ) HANDLE hf = CreateFile( m_szFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
36、 NULL, NULL ); if( hf == INVALID_HANDLE_VALUE )return 0; // 寫(xiě)文件頭 BITMAPFILEHEADER bfh; memset( &bfh, 0, sizeof( bfh ) ); bfh.bfType = ’ MB’; bfh.bfSize = sizeof( bfh ) + lBufferSize + sizeof( BITMAPINFOHEAD)E; R bfh.bfOffBits = sizeof( BITMAPINFOHEADER ) + sizeof( BITMAPFILEHEADER ); DWORD
37、dwWritten = 0; WriteFile( hf, &bfh, sizeof( bfh ), &dwWritten, NULL ); // 寫(xiě)位圖格式 BITMAPINFOHEADER bih; memset( &bih, 0, sizeof( bih ) ); bih.biSize = sizeof( bih ); bih.biWidth = lWidth; bih.biHeight = lHeight; bih.biPlanes = 1; bih.biBitCount = 24; WriteFile( hf, &bih, sizeof( bih ), &dwWr
38、itten, NULL ); // 寫(xiě)位圖數(shù)據(jù) WriteFile( hf, pBuffer, lBufferSize, &dwWritten, NULL ); CloseHandle( hf ); return 0; } }; CSampleGrabberCB mCB; ///////////////////////////////////////////////////////////////////// / // Construction/Destruction ////////////////////////////////////////////////////
39、///////////////// / CCaptureVideo::CCaptureVideo() { //COM Library Intialization if(FAILED(CoInitialize(NULL))) /*, COINIT_APARTMENTTHREADED)))*/ { AfxMessageBox("CoInitialize Failed!\r\n"); return; } m_hWnd = NULL; m_pVW = NULL; m_pMC = NULL; m_pGB = NULL; m_pCapture = NULL; } CCapt
40、ureVideo::~CCaptureVideo() { // Stop media playback if(m_pMC)m_pMC->Stop(); if(m_pVW){ m_pVW->put_Visible(OAFALSE); m_pVW->put_Owner(NULL); } SAFE_RELEASE(m_pCapture); SAFE_RELEASE(m_pMC); SAFE_RELEASE(m_pGB); SAFE_RELEASE(m_pBF); CoUninitialize( ); } int CCaptureVideo::EnumDevices(HWN
41、D hList)
{
if (!hList)
return -1;
int id = 0;
// 枚舉視頻撲捉設(shè)備
ICreateDevEnum *pCreateDevEnum;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum);
if (hr != NOERROR)return -1;
CComPtr
42、Enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0); if (hr != NOERROR)return -1; pEm->Reset(); ULONG cFetched; IMoniker *pM; while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK) { IPropertyBag *pBag; hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag); if(SUCCEEDED
43、(hr)) VARIANT var; var.vt = VT_BSTR; hr = pBag->Read(L"FriendlyName", &var, NULL); if (hr == NOERROR) { TCHAR str[2048]; id++; WideCharToMultiByte(CP_ACP,0,var.bstrVal, -1, str, 2048, NULL, NULL); ::SendMessage(hList, CB_ADDSTRING, 0,(LPARAM)str); SysFreeString(var.bstrVal); } pBag->Rele
44、ase(); } pM->Release(); } return id; } HRESULT CCaptureVideo::Init(int iDeviceID, HWND hWnd) { HRESULT hr; hr = InitCaptureGraphBuilder(); if (FAILED(hr)){ AfxMessageBox("Failed to get video interfaces!"); return hr; } // Bind Device Filter. We know the device because the id was passed
45、in if(!BindFilter(iDeviceID, &m_pBF))return S_FALSE; hr = m_pGB->AddFilter(m_pBF, L"Capture Filter"); // hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, // m_pBF, NULL, NULL); // create a sample grabber hr = m_pGrabber.CoCreateInstance( CLSID_SampleGrabber ); if( !m_pGra
46、bber ){ AfxMessageBox("Fail to create SampleGrabber, maybeqedit.dll is not registered?"); return hr; } CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabBase( m_pGrabber ); // 設(shè)置視頻格式 AM_MEDIA_TYPE mt; ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE)); mt.majortype = MEDIATYPE_Video; mt.subtype = MEDIASU
47、BTYPE_RGB24; hr = m_pGrabber->SetMediaType(&mt); if( FAILED( hr ) ){ AfxMessageBox("Fail to set media type!"); return hr; } hr = m_pGB->AddFilter( pGrabBase, L"Grabber" ); if( FAILED( hr ) ){ AfxMessageBox("Fail to put sample grabber in graph"); return hr; } // try to render preview/captu
48、re pin hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL); if( FAILED( hr ) ) hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL); if( FAILED( hr ) ){ AfxMessageBox("Can ’ t build the graph"); return hr; } hr =
49、m_pGrabber->GetConnectedMediaType( &mt ); if ( FAILED( hr) ){ AfxMessageBox("Failt to read the connected media type"); return hr; } VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mt.pbFormat; mCB.lWidth = vih->bmiHeader.biWidth; mCB.lHeight = vih->bmiHeader.biHeight; FreeMediaType(mt); hr = m_p
50、Grabber->SetBufferSamples( FALSE ); hr = m_pGrabber->SetOneShot( FALSE ); hr = m_pGrabber->SetCallback( &mCB, 1 ); // 設(shè)置視頻捕捉窗口 m_hWnd = hWnd ; SetupVideoWindow(); hr = m_pMC->Run();// 開(kāi)始視頻捕捉 if(FAILED(hr)){AfxMessageBox("Couldn ’ t run the graph!");return hr;} return S_OK; } bool CCaptureVi
51、deo::BindFilter(int deviceId, IBaseFilter **pFilter)
{
if (deviceId < 0) return false;
// enumerate all video capture devices
CComPtr
52、
if (hr != NOERROR)
{
return false;
}
CComPtr
53、), hr==S_OK, index <= deviceId) { IPropertyBag *pBag; hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag); if(SUCCEEDED(hr)) { VARIANT var; var.vt = VT_BSTR; hr = pBag->Read(L"FriendlyName", &var, NULL); if (hr == NOERROR) { if (index == deviceId) { pM->BindToObject(0, 0, IID_
54、IBaseFilter, (void**)pFilter); } SysFreeString(var.bstrVal); } pBag->Release(); } pM->Release(); index++; } return true; } HRESULT CCaptureVideo::InitCaptureGraphBuilder() { HRESULT hr; // 創(chuàng)建 IGraphBuilder 接口 hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGrap
55、hBuilder, (void **)&m_pGB); // 創(chuàng)建 ICaptureGraphBuilder2 接口 hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void **) &m_pCapture); if (FAILED(hr))return hr; m_pCapture->SetFiltergraph(m_pGB); hr = m_pGB->QueryInterface(IID_IMediaControl, (vo
56、id **)&m_pMC); if (FAILED(hr))return hr; hr = m_pGB->QueryInterface(IID_IVideoWindow, (LPVOID *) &m_pVW); if (FAILED(hr))return hr; return hr; } HRESULT CCaptureVideo::SetupVideoWindow() { HRESULT hr; hr = m_pVW->put_Owner((OAHWND)m_hWnd); if (FAILED(hr))return hr; hr = m_pVW->put_WindowS
57、tyle(WS_CHILD | WS_CLIPCHILDREN); if (FAILED(hr))return hr; ResizeVideoWindow(); hr = m_pVW->put_Visible(OATRUE); return hr; } void CCaptureVideo::ResizeVideoWindow() { if (m_pVW){ // 讓圖像充滿(mǎn)整個(gè)窗口 CRect rc; ::GetClientRect(m_hWnd,&rc); m_pVW->SetWindowPosition(0, 0, rc.right, rc.bottom); }
58、 } void CCaptureVideo::GrabOneFrame(BOOL bGrab) { bOneShot = bGrab; } void CCaptureVideo::FreeMediaType(AM_MEDIA_TYPE& mt) { if (mt.cbFormat != 0) { CoTaskMemFree((PVOID)mt.pbFormat); // Strictly unnecessary but tidier mt.cbFormat = 0; mt.pbFormat = NULL; } if (mt.pUnk != NULL) { mt.p
59、Unk->Release(); mt.pUnk = NULL; } } 如何使用視頻捕捉類(lèi) CCaptureVideo 構(gòu)建 CCaptureVideo 類(lèi)以后, 使用就方便多了, 我們?cè)诰幊讨兄恍枰且? 面三個(gè)類(lèi)成員函數(shù)就可以實(shí)現(xiàn)用攝像頭進(jìn)行視頻捕捉: ①int EnumDevices(HWND hList); 〃hList 是下拉列表框的句柄,本函數(shù) 用于枚舉當(dāng)前系統(tǒng)安裝的所有視頻捕捉設(shè)備 ② HRESULT Init(int iDeviceID,HWND hWnd); //iDeviceID 是視頻捕捉設(shè)備 序號(hào),hWn配視頻捕捉窗口的句柄 ③ void GrabOn
60、eFrame(BOOL bGrab);// 調(diào)用 GrabOneFrame(true) 就可以捕 獲當(dāng)前的靜態(tài)圖像并保存到硬盤(pán)上 具體示例:用MFC AppWizard(exe)創(chuàng)建一個(gè)對(duì)話(huà)框應(yīng)用程序,取名為 ds, 給對(duì)話(huà)框添加一個(gè)下拉列表框(IDC_COMBO1)兩個(gè)按鈕(IDC_PHOTO IDC_HAVEALOOK一個(gè) Picture 控件(ID:IDC_STATIC_SCREEType: Rectangle , Color:Gray )。 1、使用向?qū)砑映蓡T變量 CStatic m_staticScreen; // IDC_STATIC_SCREEN CComboBox m_
61、ListCtrl; // IDC_COMBO1 CCaptureVideo m_cap; 2、為 BOOL CDsDlg::OnInitDialog() 添加如下代碼: // TODO: Add extra initialization here m_cap.EnumDevices (m_ListCtrl); m_ListCtrl.SetCurSel (0); 3、為確定按鈕添加代碼如下: void CDsDlg::OnOK() { // 只需要四行代碼就可以進(jìn)行視頻捕捉了 UpdateData(); HWND hWnd = m_staticScreen.GetSafeHwnd() ; HRESULT hr = m_cap.Init(m_ListCtrl.GetCurSel (),hWnd); GetDlgItem(IDOK)->EnableWindow(FALSE); } 4、如果希望捕捉靜態(tài)圖像,為照相按鈕添加如下代碼: void CDsDlg::OnPhoto() { m_cap.GrabOneFrame(true);
- 溫馨提示:
1: 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 6.煤礦安全生產(chǎn)科普知識(shí)競(jìng)賽題含答案
- 2.煤礦爆破工技能鑒定試題含答案
- 3.爆破工培訓(xùn)考試試題含答案
- 2.煤礦安全監(jiān)察人員模擬考試題庫(kù)試卷含答案
- 3.金屬非金屬礦山安全管理人員(地下礦山)安全生產(chǎn)模擬考試題庫(kù)試卷含答案
- 4.煤礦特種作業(yè)人員井下電鉗工模擬考試題庫(kù)試卷含答案
- 1 煤礦安全生產(chǎn)及管理知識(shí)測(cè)試題庫(kù)及答案
- 2 各種煤礦安全考試試題含答案
- 1 煤礦安全檢查考試題
- 1 井下放炮員練習(xí)題含答案
- 2煤礦安全監(jiān)測(cè)工種技術(shù)比武題庫(kù)含解析
- 1 礦山應(yīng)急救援安全知識(shí)競(jìng)賽試題
- 1 礦井泵工考試練習(xí)題含答案
- 2煤礦爆破工考試復(fù)習(xí)題含答案
- 1 各種煤礦安全考試試題含答案