zoukankan      html  css  js  c++  java
  • 在C#中利用ActiveX控件进行视频采集

            在VS6.0年代,微软提供了VFW(Video For Window) 这样强大而方便的库来支持视频捕获和回放。但是无论是在。NET v1.0还是在.NET v2.0框架中,都没有提供相应的类库来支持视频捕获和回放。解决这个问题有很多种方法,比如利用平台调用P/Invoke对VFW中的功能函数进行封 装,然后再C#中进行调用。这样效率很低并且太复杂。还可以利用第三方提供的ActiveX控件来实现这个功能,这有什么好处呢?简单!!!!这也就足够 了。并且往往第三方提供的控件功能更强大。但是世界上没有免费的午餐——这种控件往往是要收费的。在这里肯定有的朋友会想到:“不是还可以利用 DX(DirectX)来实现吗,微软也提供了Manager DX托管代码的SDK”。的确,利用DX来实现视频捕获和回放是一个很好的方法,无论从效率还是效果来说都是上上之选。不幸的是:微软虽然提供了D3D、 DirectDraw、DirectSound、DirectPlayer......但是唯独没有我们感兴趣的,可以实现视频捕获的 DirectShow的SDK。据我所知,国外有开源的代码对DirectShow进行了封装,我也用过,个人感觉还不错,有兴趣的朋友可以查找一下这方 面的资料,这里我就不多说了。
            言归正传,要利用ActiveX在C#中实现视频捕获,先要做好以下准备工作:
    首先是要有VS2003或者VS2005的开发环境,这个我就不多说,相信地球人都知道。
    其次是要安装好摄像头的驱动程序,也就是说你在QQ或者MSN视频聊天时能看到你自己摄像头的图像。
    然 后是最重要的了:安装支持视频捕获的ActiveX控件!什么控件?Pegasus CapturePro。哪里下载?下载地址:http://www.cncode.com/downinfo/3504.html 这个地址应该是可以下载的,我刚刚又测试了一次。但是我不能保证它一直有效。这个控件是收费的,网上有它的评估版,相信大家也有办法,实在不行,那么给我 发Email吧,我来告诉你怎么办。安装时一直"Next"下去后就可以了。

            在VS2003中新建一个“Windows 应用程序”工程,工程建立后,首先要向“工具箱”中添加ActiveX控件具体方法是在VS2003菜单的“工具”菜单中单击“添加/移除工具箱项”。在 弹出的对话框中选择“COM 组件”选项卡,在下面的列表框中,将“Pegasus Imaging CapturePRO Control v3.0”前面的复选框选中,然后单击“确定”返回编译器编辑界面就可以了。然后将刚刚添加的控件拖放到窗体上调整好大小和位置,在属性页中修改属性。修 改属性的方法和普通控件一样,至于各个属性的含义可以参考控件的帮助文档。控件所有的方法、属性和事件在帮助文档中都有详细的说明。这里建议修改其 “Name”属性,方便以后操作,比如将Name属性改为axCap(以后axCap都表示该控件)。将axCap的Size属性改为320,240。因 为很多摄像头的默认分辨率是320X240。窗体布局大概如下图:

            然后再窗体上放一个Button控件,在该控件的单击事件中添加以下代码:
    view plaincopy to clipboardprint?
    private void butConnect_Click(object sender, System.EventArgs e)  
    ...{  
        axCap.Connect (0);        // 连接到设备  
        axCap.Preview = true;        // 开始预览  

    private void butConnect_Click(object sender, System.EventArgs e)
    ...{
        axCap.Connect (0);        // 连接到设备
        axCap.Preview = true;        // 开始预览
    }
            然后编译工程,允许程序,单击按钮应该就可以看到视频图像了。

             到这里就表示我们的操作成功了,最基本的功能实现了,这里对上述两行代码进行简单的解释。第一行axCap.Connect(0)表示将控件连接到设备 0。在Windows中,可以同时支持多个视频设备,每个设备都有一个编号。第一个设备编号0,第二个设备编号1,依次类推。由于我的电脑上只连接了一个 视频摄像头,所以视频设备的编号是0。这里也就可以看出Connect()函数的参数实际上就是视频设备的参数,至于怎样来确定视频设备对于得编号,下面 会有详细的说明。第二行axCap.Preview = true;表示打开预览。Preview属性为真时表示在控件上显示视频图像,当然要是该属性为false,我们就看不到视频了。

            下面对一些常用的,比较重要的方法和属性进行说明:
             怎样确定视频设备的编号:首先利用属性axCap .NumDevices来获取Windows中可用视频设备的数目,然后利用方法axCap .ObtainDeviceName (i)来获取该设备的名称字符串。其中参数i同Connect()函数一样,表示视频设备编号。具体的方法和实现过程可以参考以下代码:
    view plaincopy to clipboardprint?
    //判断有没用可用的捕获设备  
    if(axCap .NumDevices <0)  
     
    {  
        //没有找到可用的视频设备则报错,并退出程序  
        MessageBox.Show ("没有发现可用的设备!","错误",MessageBoxButtons.OK ,MessageBoxIcon.Error );  
        cobDevice.Items .Add("未发现可用视频设备");  
        cobDevice.SelectedIndex =0;  
    }  
    else 
    {  
        //找到则枚举所以设备,并初始化设备组合框  
        try 
        {  
            for(int i=0;i<axCap .NumDevices ;i++)  
            {  
                cobDevice.Items .Add (axCap .ObtainDeviceName (i));  
            }  
            cobDevice.SelectedIndex =0;    //设置默认设备  
        }  
        catch 
        {  
            MessageBox.Show ("初始化设备失败!","错误",MessageBoxButtons.OK ,MessageBoxIcon.Error );  
            cobDevice.Items .Add("未发现可用视频设备");  
            cobDevice.SelectedIndex =0;  
        }  

    //判断有没用可用的捕获设备
    if(axCap .NumDevices <0)

    {
        //没有找到可用的视频设备则报错,并退出程序
        MessageBox.Show ("没有发现可用的设备!","错误",MessageBoxButtons.OK ,MessageBoxIcon.Error );
        cobDevice.Items .Add("未发现可用视频设备");
        cobDevice.SelectedIndex =0;
    }
    else
    {
        //找到则枚举所以设备,并初始化设备组合框
        try
        {
            for(int i=0;i<axCap .NumDevices ;i++)
            {
                cobDevice.Items .Add (axCap .ObtainDeviceName (i));
            }
            cobDevice.SelectedIndex =0;    //设置默认设备
        }
        catch
        {
            MessageBox.Show ("初始化设备失败!","错误",MessageBoxButtons.OK ,MessageBoxIcon.Error );
            cobDevice.Items .Add("未发现可用视频设备");
            cobDevice.SelectedIndex =0;
        }
    }

            怎样修改摄像头参数:每个摄像头都有很多参数,如亮度、对比度、灰度等。有的摄像还可能提供很多特效效果,比如像框,黑白等。这些参数和效果都可通过调用底层的视频设备属性对话框来修改,具体方法请参考以下代码:
    view plaincopy to clipboardprint?
    private void butSet_Click(object sender, System.EventArgs e)  
    {  
        //调用DrawShow设置对话框  
        if (axCap .HasFilterPropertyPage (CAPTUREPRO3Lib.FILTERPROPTYPE .FILTERPROP_VIDEO_DEVICE ))  
        {  
            axCap .ShowFilterPropertyPage (CAPTUREPRO3Lib.FILTERPROPTYPE .FILTERPROP_VIDEO_DEVICE, "");  
        }  

    private void butSet_Click(object sender, System.EventArgs e)
    {
        //调用DrawShow设置对话框
        if (axCap .HasFilterPropertyPage (CAPTUREPRO3Lib.FILTERPROPTYPE .FILTERPROP_VIDEO_DEVICE ))
        {
            axCap .ShowFilterPropertyPage (CAPTUREPRO3Lib.FILTERPROPTYPE .FILTERPROP_VIDEO_DEVICE, "");
        }
    }
     

            怎样录像:首先要设置录像文件,可以通过axCap.StreamFile属性来设置录像文件路径,该属性指的是录像文件的完整路径。然后可以设置 Preview = true属性来打开预览。然后调用方法axCap.StartCapture ()来开始录像。停止录像很简单只需要调用函数axCap.EndCapture ()就可以了。可以参考以下代码:

    view plaincopy to clipboardprint?
    private void butStartCap_Click(object sender, System.EventArgs e)  
    ...{  
        if(saveFile.FileName !="") //如果设置了路径则执行操作 否则报错  
        ...{  
            if(radCapFarme.Checked )  //执行帧捕获操作  
            ...{  
                if(!flagCapingFarmes)  //如果当前没有执行其它捕获  
                ...{  
                    if(!axCap.Preview )   //打开自动预览  
                    ...{  
                        axCap.Visible =true;  
                        axCap.Preview =true;  
                        txtBack.Visible =false;  
                        butCaptureImg.Enabled =true;  
                        butPreview.Text ="停止预览";  
                    }  
                    if(chkAutoSave.Checked )  
                    ...{  
                        //如果自动保存为真则设置周期  
                        axCap.Interval =Convert.ToInt32 (txtTime.Text ,10); //先设置自动保存时间  
                    }  
                    axCap.AutoSave =chkAutoSave.Checked;   //处理自动保存  
                    axCap.AutoIncrement =chkAutoRename.Checked; //处理自动改文件名  
                    axCap.FrameFile =saveFile.FileName ;    //设置保存路径  
                    butStartCap.Text ="停止捕获";           
                    flagCapingFarmes=true;                   //设置工作进行标志 标志忙  
                    axCap.CaptureFrame ();                   //开始捕获帧  
                }  
                else        //如果当前正在进行其它捕获工作  
                ...{   
                    axCap.AutoSave =false;                 //关自动保存  
                    axCap.Interval =0;                     //自动保存周期置0  
                    butStartCap.Text ="开始捕获";  
                    flagCapingFarmes=false;                //置工作空闲标志  
                    DisConnect();                          //断开连接 关闭捕获   
                }  
            }  
            else   //执行流捕获  
            ...{  
                if(!flagCapingStream )  
                ...{  
                    axCap.VideoCompressorIndex =cobVicomp.SelectedIndex ;  
                    axCap.AudioDeviceIndex =comAudioDevice.SelectedIndex ;  
                    axCap.AudioCompressorIndex =comAudioComp.SelectedIndex ;  
                    axCap.StreamFile =saveFile.FileName ;  
                    butStartCap.Text ="停止捕获";  
                    flagCapingStream=true;  
                    if(!axCap.Preview )   //打开自动预览  
                    ...{  
                        axCap.Visible =true;  
                        axCap.Preview =true;  
                        txtBack.Visible =false;  
                        butCaptureImg.Enabled =true;  
                        butPreview.Text ="停止预览";  
                    }  
                    try 
                    ...{  
                        axCap.StartCapture ();  
                    }  
                    catch 
                    ...{  
                        MessageBox.Show ("视频编码器不可用,请重新连接设备");  
                        cobVicomp.Items.Clear ();  
                        butStartCap.Text ="开始捕获";  
                        flagCapingStream=false;  
                        axCap.Preview =false;  
                        mnuDisableLink.Enabled =false;  
                        mnuLink.Enabled =true;  
                        cobColor.Enabled =false;  
                        cobPix.Enabled =false;  
                        cobColor.Text =null;  
                        cobColor.Items.Clear ();  
                        cobPix.Text =null;  
                        cobPix.Items .Clear ();  
                        txtBack.Visible =true;  
                        chkAdvCap.Enabled =false;  
                        butPreview.Enabled =false;  
                        butSet.Enabled =false;  
                        butDeviceSet.Enabled =false;  
                        butVideoFormat.Enabled =false;  
                        butCaptureImg.Enabled =false;  
                        chkData.Enabled =false;  
                        chkTime.Enabled =false;  
                        txtLable.Enabled =false;  
                        butPreview.Text ="开始预览";  
                        butLink.Text ="连接设备";  
                        if(chkAdvCap.Checked )  
                        chkAdvCap.CheckState =CheckState.Unchecked ;  
                        visableControl(false,3);  
                    }  
                }  
                else 
                ...{  
                    if(axCap.Preview )  
                    ...{  
                        axCap.Preview =false;  
                        axCap.Visible =false;  
                        txtBack.Visible =true;  
                        butCaptureImg.Enabled =false;  
                        butPreview.Text ="开始预览";  
                    }  
                    butStartCap.Text ="开始捕获";  
                    flagCapingStream=false;  
                    axCap.EndCapture ();  
                }  
            }  
        }  
        else 
        ...{  
            MessageBox.Show ("请先设置要存储的文件!","错误",MessageBoxButtons.OK ,MessageBoxIcon.Error );  
        }  
          

    private void butStartCap_Click(object sender, System.EventArgs e)
    ...{
        if(saveFile.FileName !="") //如果设置了路径则执行操作 否则报错
        ...{
            if(radCapFarme.Checked )  //执行帧捕获操作
            ...{
                if(!flagCapingFarmes)  //如果当前没有执行其它捕获
                ...{
                    if(!axCap.Preview )   //打开自动预览
                    ...{
                        axCap.Visible =true;
                        axCap.Preview =true;
                        txtBack.Visible =false;
                        butCaptureImg.Enabled =true;
                        butPreview.Text ="停止预览";
                    }
                    if(chkAutoSave.Checked )
                    ...{
                        //如果自动保存为真则设置周期
                        axCap.Interval =Convert.ToInt32 (txtTime.Text ,10); //先设置自动保存时间
                    }
                    axCap.AutoSave =chkAutoSave.Checked;   //处理自动保存
                    axCap.AutoIncrement =chkAutoRename.Checked; //处理自动改文件名
                    axCap.FrameFile =saveFile.FileName ;    //设置保存路径
                    butStartCap.Text ="停止捕获";        
                    flagCapingFarmes=true;                   //设置工作进行标志 标志忙
                    axCap.CaptureFrame ();                   //开始捕获帧
                }
                else        //如果当前正在进行其它捕获工作
                ...{
                    axCap.AutoSave =false;                 //关自动保存
                    axCap.Interval =0;                     //自动保存周期置0
                    butStartCap.Text ="开始捕获";
                    flagCapingFarmes=false;                //置工作空闲标志
                    DisConnect();                          //断开连接 关闭捕获
                }
            }
            else   //执行流捕获
            ...{
                if(!flagCapingStream )
                ...{
                    axCap.VideoCompressorIndex =cobVicomp.SelectedIndex ;
                    axCap.AudioDeviceIndex =comAudioDevice.SelectedIndex ;
                    axCap.AudioCompressorIndex =comAudioComp.SelectedIndex ;
                    axCap.StreamFile =saveFile.FileName ;
                    butStartCap.Text ="停止捕获";
                    flagCapingStream=true;
                    if(!axCap.Preview )   //打开自动预览
                    ...{
                        axCap.Visible =true;
                        axCap.Preview =true;
                        txtBack.Visible =false;
                        butCaptureImg.Enabled =true;
                        butPreview.Text ="停止预览";
                    }
                    try
                    ...{
                        axCap.StartCapture ();
                    }
                    catch
                    ...{
                        MessageBox.Show ("视频编码器不可用,请重新连接设备");
                        cobVicomp.Items.Clear ();
                        butStartCap.Text ="开始捕获";
                        flagCapingStream=false;
                        axCap.Preview =false;
                        mnuDisableLink.Enabled =false;
                        mnuLink.Enabled =true;
                        cobColor.Enabled =false;
                        cobPix.Enabled =false;
                        cobColor.Text =null;
                        cobColor.Items.Clear ();
                        cobPix.Text =null;
                        cobPix.Items .Clear ();
                        txtBack.Visible =true;
                        chkAdvCap.Enabled =false;
                        butPreview.Enabled =false;
                        butSet.Enabled =false;
                        butDeviceSet.Enabled =false;
                        butVideoFormat.Enabled =false;
                        butCaptureImg.Enabled =false;
                        chkData.Enabled =false;
                        chkTime.Enabled =false;
                        txtLable.Enabled =false;
                        butPreview.Text ="开始预览";
                        butLink.Text ="连接设备";
                        if(chkAdvCap.Checked )
                        chkAdvCap.CheckState =CheckState.Unchecked ;
                        visableControl(false,3);
                    }
                }
                else
                ...{
                    if(axCap.Preview )
                    ...{
                        axCap.Preview =false;
                        axCap.Visible =false;
                        txtBack.Visible =true;
                        butCaptureImg.Enabled =false;
                        butPreview.Text ="开始预览";
                    }
                    butStartCap.Text ="开始捕获";
                    flagCapingStream=false;
                    axCap.EndCapture ();
                }
            }
        }
        else
        ...{
            MessageBox.Show ("请先设置要存储的文件!","错误",MessageBoxButtons.OK ,MessageBoxIcon.Error );
        }
       
    }
     

        Pegasus CapturePRO 控件是一个功能非常强大的控件,由于篇幅和时间关系这里就不一一叙述了,该控件所有的属性、方法、事件在它的帮助文档中都有详细的说明,大家在使用的时候 可以仔细阅读。我写了一个比较详细的Demo程序,该程序使用了绝大多数功能,下面我将软件的界面和源代码给出,希望对大家有所帮助。

  • 相关阅读:
    Delphi中动态创建的Panel无法改变颜色的解决办法(要把Panel的ParentBackground设为False)
    判断当前进程是否以管理员权限启动的
    在一个exe文件中查找指定内容,找到则返回起始位置, 否则返回0
    [置顶] 使用严苛模式打破Android4.0以上平台应用中UI主线程的“独断专行”
    删除IE缓存中指定的文件
    将窗体显示在 PageControl 上
    判断操作系统多久没有任何操作
    UrlDownloadFile, 线程下载文件, 带进度条
    用JSON 和 Google 实现全文翻译
    成为高效程序员的7个重要习惯
  • 原文地址:https://www.cnblogs.com/top5/p/1635276.html
Copyright © 2011-2022 走看看