vfw(Video For Windows)是常用的视频采集方式,在vc中可以方便地采集来自usb摄像头、视频采集卡等各种支持vfw方式的视频采集设备。在新建的对话框中包含"vfw.h"头文件,在Project-》Setting中包含"Vfw32.lib",创建ID为IDC_PIC的pic控件,然后加入下面的初始化和结束代码,就采集和处理自己的视频图像了。
#include "vfw.h"
HWND ghCapWnd;
CAPDRIVERCAPS gCapDrvCaps;
CString gCapFilename;
LRESULT CALLBACK FrameCallbackProc(HWND ghWnd, LPVIDEOHDR lpVData)
{
if (!ghCapWnd)
return FALSE;
//图像处理代码
return (LRESULT) TRUE ;
}
//在OnInitDialog中添加初始化代码
CWnd *pWnd;
CRect rect;
pWnd = AfxGetMainWnd()->GetDlgItem(IDC_PIC);
pWnd->GetWindowRect(&rect);
pWnd->GetSafeHwnd();
ghCapWnd = capCreateCaptureWindow((LPCTSTR)(_T("视频窗")),
WS_CHILD|WS_VISIBLE|WS_EX_CLIENTEDGE|WS_EX_DLGMODALFRAME,
0,
0,
rect.Width(),
rect.Height(),
pWnd->GetSafeHwnd(),
0);
ASSERT(ghCapWnd);
if (capDriverConnect(ghCapWnd, 0))/*判断采集窗口是否与0号捕获卡驱动程序相连接,这里采用简化的方法,因只一块捕获卡,计算机自动登记号码通常是为0*/
{
capDriverGetCaps(ghCapWnd, &gCapDrvCaps, sizeof(CAPDRIVERCAPS)); /*作默认值初始化,并得到驱动器的性能,存入CAPDRIVERCAPS结构中*/
if (gCapDrvCaps.fCaptureInitialized) //如初始化成功
{
capPreviewRate(ghCapWnd, 33); //设置预视帧频
capPreview(ghCapWnd, TRUE); /*设置成预视模式(preview),该方式是通过内存作为缓冲区来存放视频数据,它是获得视频数据的必要条件。另一种称为Overlay模式,它是不经过内存而直接将数据传入显存中。它不符合我们要求。*/
capSetCallbackOnFrame(ghCapWnd, FrameCallbackProc); //设置每帧结束后所调用的回调函数(第二部作解释)
}
else{//初始化不成功
AfxMessageBox("捕获卡初始化失败"); //初始化不成功的消息框显示
AfxGetMainWnd()->PostMessage(WM_CLOSE);//发送WM_CLOSE消息,关闭对话框
}
}
else{//连接不成功
AfxMessageBox("捕获卡连接失败"); //连接不成功的消息框显示
}
//在OnDestroy中加入结束采集代码
capDriverDisconnect(ghCapWnd); //断开视频窗口与捕获驱动程序的连接
复制内容到剪贴板
程序代码
#include "vfw.h"
HWND ghCapWnd;
CAPDRIVERCAPS gCapDrvCaps;
CString gCapFilename;
LRESULT CALLBACK FrameCallbackProc(HWND ghWnd, LPVIDEOHDR lpVData)
{
if (!ghCapWnd)
return FALSE;
//图像处理代码
return (LRESULT) TRUE ;
}
//在OnInitDialog中添加初始化代码
CWnd *pWnd;
CRect rect;
pWnd = AfxGetMainWnd()->GetDlgItem(IDC_PIC);
pWnd->GetWindowRect(&rect);
pWnd->GetSafeHwnd();
ghCapWnd = capCreateCaptureWindow((LPCTSTR)(_T("视频窗")),
WS_CHILD|WS_VISIBLE|WS_EX_CLIENTEDGE|WS_EX_DLGMODALFRAME,
0,
0,
rect.Width(),
rect.Height(),
pWnd->GetSafeHwnd(),
0);
ASSERT(ghCapWnd);
if (capDriverConnect(ghCapWnd, 0))/*判断采集窗口是否与0号捕获卡驱动程序相连接,这里采用简化的方法,因只一块捕获卡,计算机自动登记号码通常是为0*/
{
capDriverGetCaps(ghCapWnd, &gCapDrvCaps, sizeof(CAPDRIVERCAPS)); /*作默认值初始化,并得到驱动器的性能,存入CAPDRIVERCAPS结构中*/
if (gCapDrvCaps.fCaptureInitialized) //如初始化成功
{
capPreviewRate(ghCapWnd, 33); //设置预视帧频
capPreview(ghCapWnd, TRUE); /*设置成预视模式(preview),该方式是通过内存作为缓冲区来存放视频数据,它是获得视频数据的必要条件。另一种称为Overlay模式,它是不经过内存而直接将数据传入显存中。它不符合我们要求。*/
capSetCallbackOnFrame(ghCapWnd, FrameCallbackProc); //设置每帧结束后所调用的回调函数(第二部作解释)
}
else{//初始化不成功
AfxMessageBox("捕获卡初始化失败"); //初始化不成功的消息框显示
AfxGetMainWnd()->PostMessage(WM_CLOSE);//发送WM_CLOSE消息,关闭对话框
}
}
else{//连接不成功
AfxMessageBox("捕获卡连接失败"); //连接不成功的消息框显示
}
//在OnDestroy中加入结束采集代码
capDriverDisconnect(ghCapWnd); //断开视频窗口与捕获驱动程序的连接
常用函数,添加在按钮事件中即可:
capDlgVideoFormat( ghCapWnd); /*产生一视频格式对话框,这是捕获卡驱动程序中提供的,用户可通过它来选择视频格式*/
capDlgVideoSource( ghCapWnd); //产生一视频源选择对话框产生一视频源选择对话框,它也是驱动程序中带有的
capGrabFrameNoStop(ghCapWnd); //该函数从捕获卡获得的帧数据不被压缩地存入视频缓冲区中,之后将其显示出来,而采用capGrabCapFrame( )会产生图象冻结效果。
capEditCopy(ghCapWnd); //将单帧图象复制到粘帖板上
// 写视频数据存盘程序
capCaptureSequence(ghCapWnd); //开始保存AVI文件到默认的文件中"C:\Capture.avi"。
capCaptureSequenceNoFile(ghCapWnd); //结束存盘操作,但视频仍然显示