【vb精品源码栏目提醒】:网学会员为广大网友收集整理了,VB2005下通过摄像头实现视频捕捉 - 其它资料,希望对大家有所帮助!
【编程分析】微软为软件开发人员提供了一个专门用于视频捕获的 VFW Video for Windows SDK,她为在 Windows 系统中实现视频捕获提供了标准的接口,从而大大降低了程序的开发难度。
一、VFW 简介VFW 是微软公司推出的关于数字视频的一个软件包,它能使应用程序通过数字化设备从传统的模拟视频源得到数字化的视频剪辑。
VFW 的一个关键思想是播放时不需要专用硬件,为了解决数字视频数据量大的问题,需要对数据进行压缩。
它引进了一种叫 AVI 的文件标准,该标准未规定如何对视频进行捕获、压缩及播放,仅规定视频和音频该如何存储在硬盘上,以及在 AVI 文件中交替存储视频帧和与之相匹配的音频数据。
VFW 使程序员能通过发送消息或设置属性来捕获、播放和编辑视频剪辑。
VFW 主要由以下 6 个模块组成:1、AVICAP32.DLL:包含执行视频捕获的函数,它给 AVI 文件的 I/O 处理和视频、音频设备驱动程序提供一个高级接口;2、MSVIDEO.DLL:包含一套特殊的 DrawDib 函数,用来处理屏幕上的视频操作;3、MCIAVI.DRV:包括对 VFW 的 MCI 命令解释器的驱动程序;4、AVIFILE.DLL:包含由标准多媒体 I/O(mmio)函数提供的更高的命令,用来访问.AVI文件;5、压缩管理器(ICM):用于管理的视频压缩/解压缩的编译码器(Codec);6、音频压缩管理器 ACM:提供与 ICM 相似的服务,适用于波形音频。
本程序将使用第一个模块 AVICAP32.DLL,她是 Windows API 应用程序接口相关模块,用于对摄像头和其它视频硬件进行 AVI 电影和视频的截取。
她的 AVICap 窗口类支持实时的视频流捕获和单帧捕获,并提供对视频源的控制,而且能直接访问视频缓冲区,不需要生成中间文件,实时性很强,效率很高,同时,她还可将数字视频捕获到一个文件中。
要使用该动态库,在程序中需要对其中的各个常量和 API 函数进行声明,由于
VB.NET 不再提倡使用 API 函数,其集成环境也没有 API 浏览器了,故本文所使用的全部常量和函数的声明都可以在代码包中察看。
说明:以上常量名称可以改名,但要后面的保持一致;函数名称不能改变,否则无法从AVICAP32.DLL 动态库中找到入口。
调用 AVICAP32.DLL 动态库实现视频捕捉,就是在用capCreateCaptureWindowA 创建视频窗口后,再调用消息发送函数 SendMessage 发送以上相应的消息,从而实现对视频设备的控制(包括连接、设置、抓图、录像、停止、断开等) 。
二、获取视频设备驱动为了让计算机支持视频采集,那么必须安装视频设备驱动,微软提供的 AVICAP32.DLL 动态库是一个通用的摄像头视频驱动程序,在视频创建和捕捉前,需要检查当前系统中是否安装了视频设备驱动,编程方法和核心代码如下:Function LoadDevice As IntegerDim strName As StringSpace100Dim strVer As StringSpace100Dim bRet As BooleanDim N As Integer 0获取设备名称和版本信息bRetcapGetDriverDescriptionANstrName100strVer 100While bRet 继续获取下一个设备N 1 获得设备则计数 1 次获取设备名称和版本,代码同上End WhileReturn N 返回可用设备数量End Function说明:本文只是检测系统中的可用视频驱动设备数量,没有处理设备名称和版本信息,如果要在程序中显示设备的名称、版本,可以通过 strName、strVer 变量获取。
三、创建视频窗口在进行视频捕获之前必需要先创建一个视频窗口,并以它为基础进行所有的捕获及设置操作。
视频窗口用 AVICap 窗口类的“capCreateCaptureWindowA”函数来创建,其窗口风格一般为 WS_CHILD 或 WS_VISIBLE。
视频窗类似于标准控件(如 PictureBox 等) ,并具有下列功能:●动态连接或断开视频和音频输入器件●Preview 模式对视频流进行实时显示●设置捕获速率●将捕获的单帧图像保存为 DIB 格式文件●将视频流和音频流捕获到 AVI 文件中创建捕捉窗口(本文用 PictureBox 控件)的编程方法和核心代码如下:Dim Hwnd As Integer 视窗句柄Dim Cned As Boolean 连接状态Private Sub OpenPreviewWindowDim iHeight As IntegerPC.HeightDim iWidth As IntegerPC.WidthHwndcapCreateCaptureWindowA0WS_VISIBLE Or WS_CHILD00PC.WidthPC.HeightPC.Handle.ToInt320 创建视频窗口If Hwnd 0 Then 创建成功If SendMessageHwnd WM_CN 0 0 Then 设备连接成功设置视频显示速率SendMessageHwndWM_RATE640设置视频预览SendMessageHwndWM_PV10Cned True 连接标志Else 连接失败DestroyWindowHwnd 关闭设备End IfEnd IfEnd Sub四、抓取当前视频图像通 过 发 送 WM_COPY 消 息 将 当 前 视 频 单 帧 图 像 拷 贝 到 剪 贴 板 , 然 后 通 过 剪 贴 板 的GetDataObject 方法获取图像到 Image 对象,再借助图片框控件按 Jpeg 格式保存,保存时的文件名通过保存对话框设置,编程方法和核心代码如下:SaveDlg.ShowDialog 保存对话框If SaveDlg.FileName ThenDim Data As IDataObjectDim bMap As Image拷贝视频图像到剪贴板SendMessageHwndWM_COPY00从剪贴板获取图像并转换格式DataClipboard.GetDataObjectIf Data.GetDataPresentGetTypeSystem.Drawing.Bitmap Then 剪贴板上是位图bMapCTypeData.GetDataGetTypeSystem.Drawing.Bit mapImage 获取图像PC.ImagebMap 转换图像bMap.SaveSaveDlg.FileNameImaging.ImageFormat.Jpe g 保存图像End IfEnd If五、录像的实现AVICAP32.DLL 动态库支持录像功能,并将视频信息存放到 C:CAPTURE.AVI 文件中,默认的视频大小为 320×240。
录像数据占用的存储控件比较大,平均每分钟录制的图像数据约 130MB,所以,在录像前需要对磁盘剩余空间进行检测,获取磁盘剩余空间的方法有很多,如:1、用 API 函数 GetDiskFreeSpaceEx 获取;2、用 FSO文件系统对象模型实现;3、利用 WMI 获取硬盘信息;本文采用代码最简单的第二种方法,首先通过“项目添加引用”菜单项,从 COM 选项卡中选择“Microsoft Scripting Runtime”项,点击确定返回,核心代码如下:Imports Scripting 引入Function DiskSpace As LongDim F As New FileSystemObjectDim D As DriveF.GetDriveC:DiskSpaceD.FreeSpace/1024/1024End Function上面返回的磁盘剩余空间大小以 MB 为单位,检测磁盘剩余空间只是一个提示功能,实现录像控制的核心代码如下:提示磁盘剩余空间,代码略Dim Fn As StringC:CAPTURE.AVIIf IO.File.ExistsFn Then 有文件IO.File.SetAttributesFnIO.FileAttributes.Normal 改变文件属性IO.File.DeleteFn 删除文件End IfSendMessageHwndWM_REC00 录像在录像的过程中,可以通过发送 WM_STOP 消息停止录像,核心代码如下:SendMessageHwndWM_STOP00 停止六、断开设备连接在不需要捕捉图像时,应断开连接,以便释放系统资源,通过发送 WM_DisCN 消息可以断开视窗连接,然后用 DestroyWindow 函数清除视频窗口以释放资源,核心代码如下:Private Sub ClosePreviewWindowSendMessageHwndWM_DisCN00DestroyWindowHwnd 关闭视窗Cned False 断开标志End Sub【编程实现】启动
VB2005,新建应用程序项目,向窗体添加一个图片框控件 PC(视频显示) ,一个保存对话框控件 SaveDlg(设置图像保存文件名),一个主菜单控件 MenuStrip1,添加 6 个菜单项 mCn(连接)、mPic(抓图)、mRec(录像)、mStop(停止) ,mSt(提示) 、mCut(断开) ,合理布局,并根据以上分析完善代码。
安装好摄像头,运行程序,点击“连接”菜单,在图片框中就可以看到来自摄像头的图像了,有趣的是, 当摄像头对准程序运行的屏幕时, 在捕获的运行界面上出现了程序界面嵌套的效果 。
程 序 运 行 结 果 如 图 所 示 , 调 试 环 境 : WinXpVB2005 , 源 码 下 载 地 址 :http://family1.chinaok.com/down/200641/code.rar。
图:程序抓取的图片 dtc09【编程后记】本文通过 VFW 的 AVICAP32.DLL 模块实现了摄像头视频的实时采集, 采集的图像除在计算机屏幕上实时显示外,还可以通过录像功能保存到 AVI 文件,以便日后回放,如果您的视频采集设备支持语音输入 , (如数码摄像机) 那么形成的 AVI 录像文件会自动包含音频部分。
程序还可以考虑采用实时拍照的方式来“连续”监控(比如每秒抓图一次),设计这个功能可以大大节约磁盘空间,因为每秒一张的图片大小仅 10KB 左右,而平均每秒的录像数据有2MB 之多,至少是图片数据的 200 倍,具体的实现方法留给读者思考!Imports Microsoft.VisualBasicImports Microsoft.Win32VideoCampture using
VB.NETPublic Class Form1 Inherits System.Windows.Forms.FormRegion Windows 窗体设计器生成的代码 Public Sub New MyBase.New 该调用是 Windows 窗体设计器所必需的。
InitializeComponent 在 InitializeComponent 调用之后添加任何初始化End Sub窗体重写 dispose 以清理组件列表。
Protected Overloads Overrides Sub DisposeByVal disposing As Boolean If disposing Then If Not components Is Nothing Then components.Dispose End If End If MyBase.DisposedisposingEnd SubWindows 窗体设计器所必需的Private components As System.ComponentModel.IContainer注意: 以下过程是 Windows 窗体设计器所必需的可以使用 Windows 窗体设计器修改此过程。
不要使用代码编辑器修改它。
Friend WithEvents camSrc As System.Windows.Forms.PictureBoxFriend WithEvents Button1 As System.Windows.Forms.Button Private Sub InitializeComponent Me.camSrc New System.Windows.Forms.PictureBox Me.Button1 New System.Windows.Forms.Button Me.SuspendLayout camSrc Me.camSrc.Location New System.Drawing.Point8 8 Me.camSrc.Name camSrc Me.camSrc.Size New System.Drawing.Size320 240 Me.camSrc.TabIndex 0 Me.camSrc.TabStop False Button1 Me.Button1.Location New System.Drawing.Point8 256 Me.Button1.Name Button1 Me.Button1.Size New System.Drawing.Size75 32 Me.Button1.TabIndex 1 Me.Button1.Text 关闭 Form1 Me.AutoScaleBaseSize New System.Drawing.Size6 14 Me.ClientSize New System.Drawing.Size336 294 Me.Controls.AddMe.Button1 Me.Controls.AddMe.camSrc Me.Name Form1 Me.Text VideoCampture Me.ResumeLayoutFalse End SubEnd Region Private Sub Form1_LoadByVal sender As System.Object ByVal e As System.EventArgsHandles MyBase.Load MapWebcamToWindowcamSrc.Width camSrc.Height camSrc.Handle.ToInt32 End Sub Public lwndC As Integer Public Const WS_CHILD As Integer H40000000 Public Const WS_VISIBLE As Integer H10000000 Public Const SWP_NOMOVE As Short H2S Public Const SWP_NOZORDER As Short H4S Public Const WM_USER As Short H400S Public Const WM_CAP_DRIVER_CONNECT As Integer WM_USER 10 Public Const WM_CAP_DRIVER_DISCONNECT As Integer WM_USER 11 Public Const WM_CAP_SET_VIDEOFORMAT As Integer WM_USER 45 Public Const WM_CAP_SET_PREVIEW As Integer WM_USER 50 Public Const WM_CAP_SET_PREVIEWRATE As Integer WM_USER 52 Public Structure BITMAPINFOHEADER Dim biSize As Integer Dim biWidth As Integer Dim biHeight As Integer Dim biPlanes As Short Dim biBitCount As Short Dim biCompression As Integer Dim biSizeImage As Integer Dim biXPelsPerMeter As Integer Dim biYPelsPerMeter As Integer Dim biClrUsed As Integer Dim biClrImportant As Integer End Structure Public Structure BITMAPINFO Dim bmiHeader As BITMAPINFOHEADER Dim bmiColors As Integer End Structure Declare Function SetWindowPos Lib user32 ByVal hWnd As Integer ByValhWndInsertAfter As Integer ByVal x As Integer ByVal y As Integer ByVal cx As Integer ByValcy As Integer ByVal wFlags As Integer As Integer Declare Function SendMessage Lib user32 Alias SendMessageA ByVal hWnd AsInteger ByVal wMsg As Integer ByVal wParam As Short ByVal lParam As Integer As Integer Declare Function SendMessageAsBitMap Lib user32 Alias SendMessageA ByValhWnd As Integer ByVal wMsg As Integer ByVal wParam As Integer ByRef lParam AsBITMAPINFO As Integer Declare Function capCreateCaptureWindowA Lib avicap32.dll ByVal lpszWindowNameAs String ByVal dwStyle As Integer ByVal x As Integer ByVal y As Integer ByVal nWidth AsInteger ByVal nHeight As Short ByVal hWndParent As Integer ByVal nID As Integer As Integer Declare Function capGetDriverDescriptionA Lib avicap32.dll ByVal wDriver As ShortByVal lpszName As String ByVal cbName As Integer ByVal lpszVer As String ByVal cbVer AsInteger As Boolean Function capDriverConnectByVal lwnd As Integer ByVal i As Short As Boolean capDriverConnect SendMessagelwnd WM_CAP_DRIVER_CONNECT i 0 End Function Function capDriverDisconnectByVal lwnd As Integer As Boolean capDriverDisconnect SendMessagelwnd WM_CAP_DRIVER_DISCONNECT 0 0 End Function Function capSetVideoFormatByVal hCapWnd As Integer ByRef BmpFormat AsBITMAPINFO ByVal CapFormatSize As Integer As Boolean capSetVideoFormat SendMessageAsBitMaphCapWndWM_CAP_SET_VIDEOFORMAT CapFormatSize BmpFormat End Function Function capPreviewByVal lwnd As Integer ByVal f As Boolean As Boolean capPreview SendMessagelwnd WM_CAP_SET_PREVIEW f 0 End Function The capPreview function is used to initiate the streaming of images between the VFW driverand the capture window. Function capPreviewRateByVal lwnd As Integer ByVal wMS As Short As Boolean capPreviewRate SendMessagelwnd WM_CAP_SET_PREVIEWRATE wMS 0 End Function The capPreviewRate function determines the refresh rate by specifying the refresh interval inmilliseconds. In our case it is set to 66 ms 15 Frames Per second. Now we must implement the two functions referenced by the main form as follows Sub MapWebcamToWindowByRef lWidth As Integer ByRef lHeight As Integer ByRefhWnd As Integer Dim lpszName As New
VB6.FixedLengthString100 Dim lpszName As New VBFixedStringAttribute100 Dim bmp As BITMAPINFO With bmp.bmiHeader .biSize Lenbmp.bmiHeader .biWidth 320 .biHeight 240 .biPlanes 1 .biBitCount 24 End With capGetDriverDescriptionA0 lpszName.Value 100 Nothing 100 lwndC capCreateCaptureWindowAlpszName.Value WS_VISIBLE Or WS_CHILD0 0 lWidth lHeight hWnd 0 capGetDriverDescriptionA0 lpszName.Length 100 Nothing 100 lwndC capCreateCaptureWindowAlpszName.Length WS_VISIBLE Or WS_CHILD0 0 lWidth lHeight hWnd 0 If capDriverConnectlwndC 0 Then capPreviewRatelwndC 66 capPreviewlwndC True capSetVideoFormatlwndC bmp Lenbmp SetWindowPoslwndC 0 0 0 bmp.bmiHeader.biWidth bmp.bmiHeader.biHeightSWP_NOMOVE Or SWP_NOZORDER End If End Sub The MapWebcamToWindow sub performs the following tasks Retrieves the name of the first available VFW driver. Creates a capture window and attaches it to a given window handle. Connects the VFW driver to the capture window Sets the refresh rate to 15 frames per second Initiates the transfer of video between the VFW driver and capture window Sets the video format to 320x240 Moves and stretches the capture window to 320 x 240 pixels Finally we provide our CloseWebcam function to perform the cleanup Sub CloseWebcam capDriverDisconnectlwndC End Sub Dim cc As VBFixedStringAttribute Private Sub Form1_ClosedByVal sender As Object ByVal e As System.EventArgs HandlesMyBase.Closed CloseWebcam End Sub Private Sub Button1_ClickByVal sender As System.Object ByVal e As System.EventArgsHandles Button1.Click If Button1.Text 关闭 Then CloseWebcam Button1.Text 显示 Else : MapWebcamToWindowcamSrc.Width camSrc.Height camSrc.Handle.ToInt32 Button1.Text 关闭 End If End Sub Private Sub Form1_ClickByVal sender As Object ByVal e As System.EventArgs HandlesMyBase.Click MsgBoxVideoCampture Power By wgscd 自由奔腾 2004-12 QQ:153964481E-mail:wgscd126.com www.wgscd.com MsgBoxStyle.OKOnly 版权所有 End SubEnd Class