C#调用两个至多个USB摄像头的问题

271 篇文章 2 订阅
215 篇文章 2 订阅

作者:david_6_2_2

转自:http://blog.csdn.net/david_6_2_2/article/details/6212930


using   System;
using   System.Collections.Generic;
using   System.Text;
using   System.Runtime.InteropServices;
using System.Drawing;

namespace   USBcamera
{
        public   class   VideoWork
        {
                private   const   int   WM_USER   =   0x400;
                private   const   int   WS_CHILD   =   0x40000000;
                private   const   int   WS_VISIBLE   =   0x10000000;
                private   const   int   WM_CAP_START   =   WM_USER;
                private   const   int   WM_CAP_STOP   =   WM_CAP_START   +   68;
                private   const   int   WM_CAP_DRIVER_CONNECT   =   WM_CAP_START   +   10;
                private   const   int   WM_CAP_DRIVER_DISCONNECT   =   WM_CAP_START   +   11;
                private   const   int   WM_CAP_SAVEDIB   =   WM_CAP_START   +   25;
                private   const   int   WM_CAP_GRAB_FRAME   =   WM_CAP_START   +   60;
                private   const   int   WM_CAP_SEQUENCE   =   WM_CAP_START   +   62;
                private   const   int   WM_CAP_FILE_SET_CAPTURE_FILEA   =   WM_CAP_START   +   20;
                private   const   int   WM_CAP_SEQUENCE_NOFILE   =   WM_CAP_START   +   63;
                private   const   int   WM_CAP_SET_OVERLAY   =   WM_CAP_START   +   51;
                private   const   int   WM_CAP_SET_PREVIEW   =   WM_CAP_START   +   50;
                private   const   int   WM_CAP_SET_CALLBACK_VIDEOSTREAM   =   WM_CAP_START   +   6;
                private   const   int   WM_CAP_SET_CALLBACK_ERROR   =   WM_CAP_START   +   2;
                private   const   int   WM_CAP_SET_CALLBACK_STATUSA   =   WM_CAP_START   +   3;
                private   const   int   WM_CAP_SET_CALLBACK_FRAME   =   WM_CAP_START   +   5;
                private   const   int   WM_CAP_SET_SCALE   =   WM_CAP_START   +   53;
                private   const   int   WM_CAP_SET_PREVIEWRATE   =   WM_CAP_START   +   52;
                private   IntPtr   hWndC;
                private IntPtr hWndC_1;
                private   bool   bWorkStart   =   false;
                private bool bWorkStart_1 = false;
                private   IntPtr   mControlPtr;
                private IntPtr mControlPtr_1;
                private   int   mWidth;
                private   int   mHeight;
                private   int   mLeft;
                private   int   mTop;


                /**/
                ///   <summary>
                ///   初始化显示图像
                ///   </summary>
                ///   <param   name= "handle "> 控件的句柄 </param>
                ///   <param   name= "left "> 开始显示的左边距 </param>
                ///   <param   name= "top "> 开始显示的上边距 </param>
                ///   <param   name= "width "> 要显示的宽度 </param>
                ///   <param   name= "height "> 要显示的长度 </param>
                public   VideoWork(IntPtr   handle,   int   left,   int   top,   int   width,   int   height)
                {
                        mControlPtr   =   handle;
                        mControlPtr_1 = handle;
                        mWidth   =   width;
                        mHeight   =   height;
                        mLeft   =   left;
                        mTop   =   top;
                }
       
                [DllImport( "avicap32.dll ")]
       
                private   static   extern   IntPtr capCreateCaptureWindowA(byte[] lpszWindowName,int dwStyle,int x,int y,int nWidth,int nHeight,IntPtr hWndParent, int nID);
            [DllImport("avicap32.dll ")]
                private static extern IntPtr capCreateCaptureWindowB(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID); /*新加的一个API调用,但是在编译的时候出错,提示“无法在 DLL“avicap32.dll ”中找到名为“capCreateCaptureWindowB”的入口点。”*/
       


                [DllImport( "avicap32.dll ")]
                private   static   extern   int   capGetVideoFormat(IntPtr   hWnd,   IntPtr   psVideoFormat,   int   wSize);

                //
                //这里特别注意,因为WinAPI中的long为32位,而C#中的long为64wei,所以需要将lParam该为int
                //
                [DllImport( "User32.dll ")]
                private   static   extern   bool   SendMessage(IntPtr   hWnd,   int   wMsg,   int   wParam,   int   lParam);

                /**/
                ///   <summary>
                ///   开始显示图像
                ///   </summary>
                public   void   Start()
                {
                    if (bWorkStart)
                        return;

                        bWorkStart   =   true;
                        byte[]   lpszName   =   new   byte[100];

                        hWndC   =   capCreateCaptureWindowA(lpszName,   WS_CHILD   |   WS_VISIBLE,   mLeft,   mTop,   mWidth,   mHeight,   mControlPtr,   0);

                        if   (hWndC.ToInt32()   !=   0)
                        {
                                SendMessage(hWndC,   WM_CAP_SET_CALLBACK_VIDEOSTREAM,   0,   0);
                                SendMessage(hWndC,   WM_CAP_SET_CALLBACK_ERROR,   0,   0);
                                SendMessage(hWndC,   WM_CAP_SET_CALLBACK_STATUSA,   0,   0);
                                SendMessage(hWndC,   WM_CAP_DRIVER_CONNECT,   0,   0);
                                SendMessage(hWndC,   WM_CAP_SET_SCALE,   1,   0);
                                SendMessage(hWndC,   WM_CAP_SET_PREVIEWRATE,   66,   0);
                                SendMessage(hWndC,   WM_CAP_SET_OVERLAY,   1,   0);
                                SendMessage(hWndC,   WM_CAP_SET_PREVIEW,   1,   0);
                                //Global.log.Write( "SendMessage ");
                        }
                        return;

                }
            //[DllImport("avicap32.dll ")]//add a window
            //private static extern IntPtr capCreateCaptureWindowB(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID);
            public void Start(int i)///这是我新添的一个方法,想用来调用另外一个摄像头,
            {
                //if (bWorkStart_1)
                   // return;

                bWorkStart_1 = true;
                byte[] lpszName_1 = new byte[100];

                hWndC_1 = capCreateCaptureWindowB(lpszName_1, WS_CHILD | WS_VISIBLE, mLeft, mTop, mWidth, mHeight, mControlPtr_1, 0);

                if (hWndC_1.ToInt32() != 0)
                {
                    SendMessage(hWndC_1, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 1);
                    SendMessage(hWndC_1, WM_CAP_SET_CALLBACK_ERROR, 0, 0);
                    SendMessage(hWndC_1, WM_CAP_SET_CALLBACK_STATUSA, 0, 0);
                    SendMessage(hWndC_1, WM_CAP_DRIVER_CONNECT, 1,0);
                    SendMessage(hWndC_1, WM_CAP_SET_SCALE, 1, 0);
                    SendMessage(hWndC_1, WM_CAP_SET_PREVIEWRATE, 66, 0);
                    SendMessage(hWndC_1, WM_CAP_SET_OVERLAY, 1, 0);
                    SendMessage(hWndC_1, WM_CAP_SET_PREVIEW, 1, 0);
                    //Global.log.Write( "SendMessage ");
                }
                return;

            }
                /**/
                ///   <summary>
                ///   停止显示
                ///   </summary>
                public   void   Stop()
                {
                        SendMessage(hWndC,   WM_CAP_DRIVER_DISCONNECT,   0,   0);
                        bWorkStart   =   false;
                }

                /**/
                ///   <summary>
                ///   抓图
                ///   </summary>
                ///   <param   name= "path "> 要保存bmp文件的路径 </param>
                public   void   GrabImage(string   path)
                {
                        IntPtr   hBmp   =   Marshal.StringToHGlobalAnsi(path);
                       //SendMessage(hWndC,   WM_CAP_SAVEDIB,   0,   hBmp.ToInt32());
                }
           
        }
}

 

 

 

主窗体中的调用方法是

 private void Form1_Load(object sender, EventArgs e)
        {
                       

           VideoWork   VideoA = new VideoWork(pictureBox1.Handle, 0, 0, pictureBox1.Width, pictureBox1.Height);
           VideoWork   VideoB = new VideoWork(label1.Handle, 0, 0, label1.Width, label1.Height);
            VideoA.Start();
            VideoB.Start(1);
                 


        }

 

 

以上的代码是一个调用摄像头的类,去掉红色的字体部分,调用一个摄像头是没问题。我查阅了一些资料,有专家介绍说

创建一个AVICap捕获窗口:

       使用capCreateCaptureWindow 函数可以创建一个AVICap的捕获窗口。这个函数返回一个窗口句柄,这个句柄就是捕获窗口的句柄,后面其他操作就是通过发送消息给该句柄来实现。你可以在一个程序中创建多个捕获窗口,并且每个窗口连接到不同的捕获设备上。


 

建立捕获窗口到捕获设备的连接:

你可以动态地连接或断开捕获窗口与设备间的链接。通过使用WM_CAP_DRIVR_CONNECT消息(或capDriverConnect宏),可以实现捕获窗体与设备驱动间的连接。当捕获窗体和捕获设备驱动连接后,你就可以发送针对设备的消息给该窗体了。

如果你的系统安装了多个捕获设备,你可以通过在发送WM_CAP_DRIVER_CONNECT消息时,设置wPrarm参数(integer)。来指定捕获窗口与那个具体的视频捕获设备相连接。

WPrarm参数是一个整数,它表示一个系统已经安装的视频捕获设备列表的索引(注册表中或这System.ini [drivers]中的信息)。该列表的索引从0开始。

       通过capGetDriverDescription函数可以获得安装的捕获驱动程序的名称和版本。你的应用程序可以使用这个函数列举除安装的所有捕获设备,让用户可以选择其中一个去与捕获窗口相联。

通过发送WM_CAP_DRIVER_GET_NAME消息(capDriverGetName宏),可以获得与指定窗体连接的捕获设备的名称。通过发送WM_CAP_DRIVER_GET_VERSION消息(capDriverGetVersion宏),可以获得与指定窗体连接的捕获设备的版本。

通过发送WM_CAP_DRIVER_DISCONNECT消息(capDriverGetDisconnect宏),可以断开连接。当捕获窗体销毁后,任何连接的视频捕获设备都将自动断开。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/suntaoznz/archive/2005/08/06/447067.aspx

 

 

我按照上面的思路就在VideoWork类中加上了红色的代码,接上两个摄像头,试图调用两个摄像头。但是没有成功,并有如以上注解所示的错误。

请高人帮我指点一下,我该如何解决这个问题。


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值