VC捕捉攝像頭圖像入門源碼要點
《VC捕捉攝像頭圖像入門源碼要點》由會員分享,可在線閱讀,更多相關《VC捕捉攝像頭圖像入門源碼要點(16頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、 【轉】VC捕捉攝像頭圖像入門源碼 VC捕捉攝像頭圖像入門源碼(非常適合新手)(轉) 默認分類2009-11-02 17:46:56 閱讀39評論0字號:大中 小 〃此源碼是我更改過的基于 VFW(Video for Windows)的源碼,使用了定時器能 實時的顯示圖像,從網(wǎng)上可搜到原版源碼,但是原版的功能是保存為一個文件, 且不能實時顯示,此版本雖然能顯示,但感覺反應速度不是很快,沒有基于 DirectShow的程序更新速度快,不過在 WM_PAINT息處理里加 while(1){capGrabFrame(ghWndCap);}刷新速度就快很多了,但是這樣程序就進 入死循環(huán)不
2、能再處理其他消息,至于怎樣改進,就靠讀者你了。
//源碼的任何部分都可以在 MSDN!查至IJ,請參考 MSDN
#include
3、"CamCapture.AVI"; ///////////////////////////////////////////////////////////////////// // // StatusCallbackProc: 冊這個回調(diào)函數(shù)。 // hWnd: // nID: // lpStatusText: 狀態(tài)回調(diào)函數(shù),使用capSetCallbackOnStatus 宏來注 捕獲窗體句柄 當前狀態(tài)的狀態(tài)碼 當前狀態(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: 錯誤回調(diào)函數(shù) , 過 capSetCallbackOnError 宏來 注冊回調(diào) 捕獲窗口句柄 錯誤代碼 關于錯誤的文本信息 // hWnd: // nErrID: // lpErrorText: ///////////////////////////////////////////////////////////////////// ////////// LRESULT CALLBACK ErrorCallbackProc(HWND hWnd,int
7、nErrID,LPSTR lpErrorText) { if(!ghWndCap) return FALSE; if(nErrID==0) return TRUE;// 清除舊的錯誤 wsprintf(gachBuffer,"Error# %d",nErrID);// 顯示錯誤標識和文本 MessageBox(hWnd, lpErrorText, gachBuffer,MB_OK | MB_ICONEXCLAMATION); return (LRESULT) TRUE; } ///////////////////////////////////////////////////
8、////////////////// ///////// // FrameCallbackProc: 幀回調(diào)函數(shù) , 通過 capSetCallbackFrame 宏來注冊 捕獲窗體句柄 指向一個包含幀信息的數(shù)據(jù)結構體 回調(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;// 假設 fp 為一打開的 .dat 文件指針 fwrite(lpVHdr->lpData,1,lpVHdr->dwBufferLength,fp); return (LRESULT)TRUE; } ///////////////////////////////////////////////////////////////////// ///////// //TimerProc 函數(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ū)動連接 capDriverGetCaps(ghWndCap,&gCapDriverCaps,sizeof(CAPDRIVERCAPS)) ;// 獲得驅(qū)動的能力 , 相關的信息放在結構變量 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ū)動器是否有疊加能力 capOverlay(ghWndCap,TRUE); // 啟動 Overlay 模式 if(gCapDriverCaps.fHasDlgVideoSource)capDlgVideoSo
15、urce(ghWndCap); //Video source 對話框 if(gCapDriverCaps.fHasDlgVideoFormat)capDlgVideoFormat(ghWndCap); // Video format 對話框 if(gCapDriverCaps.fHasDlgVideoDisplay)capDlgVideoDisplay(ghWndCa p); // Video display 對話框 // capFileSetCaptureFile( ghWndCap,szCaptureFile); // 將要保存的文 件名設為本源文件開頭處的全局字符串常量
16、// capFileAlloc(ghWndCap, (1024L * 1024L * 5)); // 為捕獲文件分配存 儲空間 capCaptureSequence(ghWndCap); // 開始捕獲視頻序列 // 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ū)動斷開 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 進行視頻捕捉 (捕捉靜態(tài)圖像) 的編程思路, 并提供針對攝像頭編程的一個視頻捕捉類 CcaptureVideo 和一個示例。 、戶 、. 前言 DirectShow是微軟公司提供的一套在 Windows平臺上進行流媒體處理的開 發(fā)包,與 DirectX 開發(fā)包一起發(fā)布。 DirectShow 為多媒體流的捕捉和回放提供 了強有力的支持。用
23、DirectShow 開發(fā)應用程序,我們可以很方便地從支持 WDM 驅(qū)動模型的采集卡上捕獲數(shù)據(jù),并且進行相應的后期處理乃至存儲到文件中。 DirectShow是基于COM勺,為了編寫 DirectShow應用程序,需要了解 COM 客戶程序編寫的基礎知識。 DirectShow 提供了大量的接口,但在編程中發(fā)現(xiàn)還 是不夠方便, 如果能構建一個視頻捕捉類把常用的一些動作封裝起來, 那么就更 方便了。 編程思路 為了更加容易建立視頻捕捉應用程序, DirectShow 提供了一個叫做 Capture Graph Builder 的對象, Capture Graph Builder
24、提供 IcaptureGraphBuilder2 接口,該接口可以建立和控制 Capture Graph 。 建立視頻捕捉程序,必須首先獲取并初始化 IcaptureGraphBuilder2 接口, 然后選擇一個適當?shù)囊曨l捕捉設備。選擇好設備后,為該設備創(chuàng)建 Capture filter ,然后調(diào)用 AddFilter 把 Capture filter 添加到 Filter Graph 。 如果僅僅希望用攝像頭來進行實時監(jiān)控的話,只需要在上面的基礎上調(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 提供了一個捕捉靜態(tài)圖像的方法: 使用 SampleGrabber filter 。 依次按照以下三個步驟就可以了: 第一步 , 定義一個類實現(xiàn) Sample
26、 Grabber 的回調(diào)接口 IsampleGrabberCB : class CSampleGrabberCB : public ISampleGrabberCB { // 在后面提供的類中具體完成 } CSampleGrabberCB mCB; 第二步、調(diào)用 RenderStream 依次把 Still pin 、 Sample Grabber 和系統(tǒng)默 認 Renderer Filter 連接起來。 第三步、配置 Sample Grabber 以捕獲數(shù)據(jù)。 視頻捕捉類 CCaptureVideo 的具體實現(xiàn) // CCaptureVideo 視頻捕捉類頭文件 /////
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 視頻捕捉類實現(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];〃位圖文件名稱 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; // 寫文件頭 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 ); // 寫位圖格式 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 ); // 寫位圖數(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;
// 枚舉視頻撲捉設備
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 ); // 設置視頻格式 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 ); // 設置視頻捕捉窗口 m_hWnd = hWnd ; SetupVideoWindow(); hr = m_pMC->Run();// 開始視頻捕捉 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){ // 讓圖像充滿整個窗口 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; } } 如何使用視頻捕捉類 CCaptureVideo 構建 CCaptureVideo 類以后, 使用就方便多了, 我們在編程中只需要是要下 面三個類成員函數(shù)就可以實現(xiàn)用攝像頭進行視頻捕捉: ①int EnumDevices(HWND hList); 〃hList 是下拉列表框的句柄,本函數(shù) 用于枚舉當前系統(tǒng)安裝的所有視頻捕捉設備 ② HRESULT Init(int iDeviceID,HWND hWnd); //iDeviceID 是視頻捕捉設備 序號,hWn配視頻捕捉窗口的句柄 ③ void GrabOn
60、eFrame(BOOL bGrab);// 調(diào)用 GrabOneFrame(true) 就可以捕 獲當前的靜態(tài)圖像并保存到硬盤上 具體示例:用MFC AppWizard(exe)創(chuàng)建一個對話框應用程序,取名為 ds, 給對話框添加一個下拉列表框(IDC_COMBO1)兩個按鈕(IDC_PHOTO IDC_HAVEALOOK一個 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() { // 只需要四行代碼就可以進行視頻捕捉了 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: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 市教育局冬季運動會安全工作預案
- 2024年秋季《思想道德與法治》大作業(yè)及答案3套試卷
- 2024年教師年度考核表個人工作總結(可編輯)
- 2024年xx村兩委涉案資金退還保證書
- 2024年憲法宣傳周活動總結+在機關“弘揚憲法精神推動發(fā)改工作高質(zhì)量發(fā)展”專題宣講報告會上的講話
- 2024年XX村合作社年報總結
- 2024-2025年秋季第一學期初中歷史上冊教研組工作總結
- 2024年小學高級教師年終工作總結匯報
- 2024-2025年秋季第一學期初中物理上冊教研組工作總結
- 2024年xx鎮(zhèn)交通年度總結
- 2024-2025年秋季第一學期小學語文教師工作總結
- 2024年XX村陳規(guī)陋習整治報告
- 2025年學校元旦迎新盛典活動策劃方案
- 2024年學校周邊安全隱患自查報告
- 2024年XX鎮(zhèn)農(nóng)村規(guī)劃管控述職報告