 |
簡介與下載
程式介面文件
範例程式碼
Video Grabber Library
這是簡單的 MFC 對話盒應用程式 vdoview.exe. 在 stdafx.h 與 vdoview.h 檔案當中都是些尋常的
MFC 典型程式碼, 幾乎所有的工作都是在 vdoview.cpp 完成的. 在底下的範例程式碼當中,
相關的述句都已經以黑色的粗體字標示.
在 CVideoApp::InitInstance( ) 呼叫了 CoInitialize(NULL) 以便啟用系統中的 COM
物件, 然後在 CVideoDlg::OnInitDialog( ) 中呼叫了 GrabberOpen( ) 來連接 camera
並指定 callback 函式GrabberCallback( ). 在 CVideoDlg 類別當中準備了一個 bitmap
header 以便描繪接收到的影像. 所以當 Start 按鈕被按下, GrabberStart( ) 被呼叫以後, 這個
callback function 就會持續地收到影像, 所以它把影像複製到 pDlg->pBits 並且要求重繪畫面.
vdoview.h
/** @file vdoview.h
* @brief Declarations.
* The file declares the dialog and application classes of this dialog-based
program that demonstrates the usage of vdograb.lib.
* @author Shu-Kai Yang (http://shukaiyang.myweb.hinet.net/)
* @date 2006/11/25 */
#include "resource.h" // main symbols
#define DEVICE_NAME NULL
// #define DEVICE_NAME L"USB 2.0 1.3M UVC WebCam"
class CVideoApp : public CWinApp
{
// Overrides
public:
virtual BOOL InitInstance();
// Implementation:
DECLARE_MESSAGE_MAP()
};
// CVideoDlg dialog
class CVideoDlg : public CDialog
{
public:
// Dialog Data:
enum { IDD = IDD_VDOVIEW_DIALOG };
BITMAPINFOHEADER header;
LPBYTE pBits;
protected:
HICON m_hIcon;
// Construction
public:
CVideoDlg(CWnd * pParent = NULL);
// Implementation
protected:
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnDestroy();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnBnClickedStart();
afx_msg void OnBnClickedStop();
DECLARE_MESSAGE_MAP()
};
vdoview.cpp
/** @file vdoview.cpp
* @brief Implementations.
* The file implements the dialog and application classes of the dialog-based
application that demonstrates the usage of vdograb.dll. When the dialog is
being initialized, it opened the video-capturing device (web camera). Then
when the user clicks the "Start" button, the dialog receives the captured
images via the callback function and renders the images.
* @author Shu-Kai Yang (http://shukaiyang.myweb.hinet.net/)
* @date 2006/11/26 */
#include "stdafx.h"
#include "vdoview.h"
#include "../vdograb/vdograb.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// The one and only CVideoApp object:
CVideoApp theApp;
void GrabberCallback(void *, int, int, int);
// CVideoApp message map:
BEGIN_MESSAGE_MAP(CVideoApp, CWinApp)
END_MESSAGE_MAP()
// CVideoApp initialization"
BOOL CVideoApp::InitInstance()
{
// Typical MFC initializations:
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
CoInitialize(NULL);
// Disaplay a dialog and set it the main window of the application:
CVideoDlg dlg;
m_pMainWnd = &dlg;
dlg.DoModal();
CoUninitialize();
return FALSE;
}
// CVideoDlg dialog
CVideoDlg::CVideoDlg(CWnd * pParent) : CDialog(CVideoDlg::IDD, pParent), pBits(NULL)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
// Fill the dummy bitmap header for DIB rendering:
header.biSize = sizeof(BITMAPINFOHEADER);
header.biPlanes = 1;
header.biBitCount = 24;
header.biCompression = BI_RGB;
header.biXPelsPerMeter = 120;
header.biYPelsPerMeter = 120;
header.biClrUsed = 0;
header.biClrImportant = 0;
}
BEGIN_MESSAGE_MAP(CVideoDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_START, &CVideoDlg::OnBnClickedStart)
ON_BN_CLICKED(IDC_STOP, &CVideoDlg::OnBnClickedStop)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// CVideoDlg message handlers:
BOOL CVideoDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog:
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);
// Enable the video capturing at beginning:
if (GrabberOpen(DEVICE_NAME, GrabberCallback) == FALSE)
{ AfxMessageBox(L"Can not open the camera device!", MB_ICONSTOP | MB_OK);
return FALSE; }
return TRUE;
}
void CVideoDlg::OnDestroy()
{
// Stop the video capturing when closing the window:
GrabberClose();
if (pBits) { delete pBits; }
CDialog::OnDestroy();
}
// The system calls this function to obtain the cursor to display
// while the user drags the minimized window.
HCURSOR CVideoDlg::OnQueryDragIcon()
{ return static_cast<HCURSOR>(m_hIcon); }
void CVideoDlg::OnBnClickedStart()
{
if(GrabberStart() == FALSE)
{ AfxMessageBox(L"Can not start the video capturing!", MB_ICONSTOP | MB_OK); }
}
void CVideoDlg::OnBnClickedStop()
{ GrabberStop(); }
void CVideoDlg::OnPaint()
{
CRect rect;
if (IsIconic())
{
// If you add a minimize button to your dialog, you will need the code below to draw the
// icon. For MFC applications using the document/view model, this is automatically done
// for you by the framework.
CPaintDC dc(this);
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle:
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon:
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
// The captured data is already a bottom-up DIB image, so stretch it:
CWnd * pCanvas = GetDlgItem(IDC_CANVAS);
if((pCanvas) && (pBits))
{
CPaintDC dc(pCanvas);
dc.SetStretchBltMode(HALFTONE);
pCanvas->GetClientRect(&rect);
::StretchDIBits(dc.GetSafeHdc(), 0, 0, rect.Width(), rect.Height(),
0, 0, header.biWidth, header.biHeight, pBits, (BITMAPINFO *)&header,
DIB_RGB_COLORS, SRCCOPY);
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Callback Function for the Library:
void GrabberCallback(void * pBits, int width, int height, int size)
{
// Get the dialog window and Retrieve the canvas window for rendering:
CVideoDlg * pDlg = (CVideoDlg *)(theApp.m_pMainWnd);
if(pDlg == NULL) { return; }
TRACE(L"GrabberCallback(%dx%d, %d bytes)\n", width, height, size);
// Fill bitmap header for DIB rendering:
pDlg->header.biWidth = width;
pDlg->header.biHeight = height;
pDlg->header.biSizeImage = size;
// Copy the pixels to the dialog, allocating the memory when necessary:
if (pDlg->pBits == NULL) { pDlg->pBits = new BYTE[size]; }
if (pDlg->pBits) { memcpy(pDlg->pBits, pBits, size); }
pDlg->Invalidate(FALSE);
}
Last updated at 2006 / 11 / 27 by Shu-Kai Yang.
|
|