使用不带DirectShow的网络摄像头. [英] Using a Webcam without DirectShow.

查看:86
本文介绍了使用不带DirectShow的网络摄像头.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我想知道是否有一种方法可以使集成的网络摄像头在不使用外部DLL(例如DirectShow等)的情况下工作.我在网上找到了一些代码,但是某些设备ID尚未设置或它需要外部引用.以下使用System 32 API调用,但是设备ID保持空白,不确定如何设置!

  class  WebCamera:IDisposable
    {
         #region常量
 ///  <  摘要 > 
 /// 常量用于重载非托管代码功能
 /// 每个常量代表一个状态
 ///  <  /summary  > 
 私有  const   WM_CAP = 0x400;
        私有  const   int  WM_CAP_DRIVER_CONNECT = 0x40a;
        私有  const   int  WM_CAP_DRIVER_DISCONNECT = 0x40b;
        私有  const   int  WM_CAP_EDIT_COPY = 0x41e;
        私有  const   int  WM_CAP_SET_PREVIEW = 0x432;
        私有  const   int  WM_CAP_SET_OVERLAY = 0x433;
        私有  const   int  WM_CAP_SET_PREVIEWRATE = 0x434;
        私有  const   int  WM_CAP_SET_SCALE = 0x435;
        私有  const   int  WS_CHILD = 0x40000000;
        私有  const   int  WS_VISIBLE = 0x10000000;
        私有  const   short  SWP_NOMOVE = 0x2;
        私有  SWP_NOZORDER = 0x4;
        私有  HWND_BOTTOM =  1 ;
         #endregion

         #region DLL和属性
 ///  <  摘要 > 
 ///  DllImport允许您在系统上导入dll,以使您的代码与之最小化
 /// 此功能可枚举WebCam设备
 ///  <  /summary  > 
 [DllImport(" )]]
        受保护的 静态 外部  short  wDriverIndex,
                                                              [MarshalAs(UnmanagedType.VBByRefStr)] 引用 字符串 IpszName,
                                                               int  cbName,[MarshalAs(UnmanagedType.VBByRefStr)]  ref  字符串 IpszVer, int  cbVer);
        ///  <  > 
 ///  DllImport允许您在系统上导入dll,以使您的代码与之最小化
 /// 创建一个窗口子级,以便您可以在PictureBox中显示它
 ///  <  /summary  > 
 [DllImport(" )]]
        受保护的 静态 外部  int  capCreateCaptureWindowA([MarshalAs(UnmanagedType.VBByRefStr)] 字符串 lpszWindowName,
                                                             int  dwStyle, int  x, int  y , int  nWidth, int  nHeight, int  hWndParent, int  nID);

        ///  <  > 
 ///  DllImport允许您在系统上导入dll,以使您的代码与之最小化
 /// 此功能可对子窗口的大小,位置和Z顺序进行设置更改
 ///  <  /summary  > 
 ///  <  参数   名称="hwnd"  <  > 
 ///  <  参数   名称="hWndInsertAfter"  <  > 
 ///  <  参数   名称="x"  <  > 
 ///  <  参数   名称="y"  <  > 
 ///  <  参数   名称="cx"  <  > 
 ///  <  参数   名称="cy"  <  > 
 ///  <  参数   名称="wFlags"  <  > 
 ///  <  返回 >  <  > 
 [DllImport(" )]
        受保护的 静态 外部  int  hwnd, int  x, int  y, int  cx, int  cy, int  wFlags);

        ///  <  > 
 ///  DllImport允许您在系统上导入dll,以使您的代码与之最小化
 /// 此功能可将指定的消息发送到一个或多个窗口
 ///  <  /summary  > 
 ///  <  参数   名称="hwnd"  <  > 
 ///  <  参数   名称="wMsg"  <  > 
 ///  <  参数   名称="wParam"  <  > 
 ///  <  参数   名称="lParam"  <  > 
 ///  <  返回 >  <  > 
 [DllImport(" ,EntryPoint = " )]
        受保护的 静态 外部  int  hwnd,对象 lParam);

        ///  <  > 
 ///  DllImport允许您在系统上导入dll,以使您的代码与之最小化
 /// 此功能可以销毁窗口子级
 ///  <  /summary  > 
 ///  <  参数   名称="hwnd"  <  > 
 ///  <  返回 >  <  > 
 [DllImport(" )]
        受保护的 静态 外部  int  hwnd);

        // 常规设备ID 
         int  DeviceID =  0 ;
        // 处理要预览窗口的值
         int  hHwnd =  0 ;
        // 设备列表
        ArrayList ListOfDevices =  ArrayList();
        // 在PictureBox中显示流
        公共 PictureBox容器{ get ; 设置; }
         #endregion

         #region加载方法
 // 连接到设备.
        ///  <  > 
 /// 此函数用于加载设备列表
 ///  <  /summary  > 
 公共  void  Load()
        {
            字符串名称= 字符串 .Empty.PadRight( 100 );
            字符串版本= 字符串 .Empty.PadRight( 100 );
            布尔 EndOfDeviceList =  false ;
            索引=  0 ;

            // 将所有可用设备加载并命名为ListOfDevices 
            
            {
                // 获取驱动程序名称和版本
                EndOfDeviceList = capGetDriverDescriptionA(index, ref 名称, 100  ref 版本, 100 );
                //  
                如果(EndOfDeviceList)ListOfDevices.Add(Name.Trim());
                索引+ =  1 ;
            }
             while (!(EndOfDeviceList ==  false ));
        }
         #endregion

         #region打开连接
 公共  void  OpenConnection()
        {
            加载();

            字符串 DeviceIndex = Convert.ToString(DeviceID);
            // 设置容器(图片框)以处理设备
             IntPtr  oHandle = Container.Handle;
            {
                MessageBox.Show(" );
            }

            // 在图片框中打开预览"窗口.
            // 使用capCreateCaptureWindowA创建一个子窗口,以便可以在图片框中显示它.
            hHwnd = capCreateCaptureWindowA( ref  DeviceIndex,WS_VISIBLE | WS_CHILD, 0  0  640  480 ,oHandle.ToInt32(),// 连接到设备
            如果(SendMessage(hHwnd,WM_CAP_DRIVER_CONNECT,DeviceID, 0 )!== // 设置预览比例
                SendMessage(hHwnd,WM_CAP_SET_SCALE,-1, 0 );
                // 设置预览速率(以毫秒为单位)
                SendMessage(hHwnd,WM_CAP_SET_PREVIEWRATE, 66  0 );
                // 开始预览相机中的图像
                SendMessage(hHwnd,WM_CAP_SET_PREVIEW,-1, 0 );
                // 调整窗口大小以适合PictureBox 
                SetWindowPos(hHwnd,HWND_BOTTOM, 0  0 ,Container.Height,Container.Width,SWP_NOMOVE | SWP_NOZORDER) ;
            }
            其他
            {
                // 由于连接错误而关闭设备
                DestroyWindow(hHwnd);
            }
        }
         #endregion

         #region关闭连接
 公共  void  CloseConnection()
        {
            SendMessage(hHwnd,WM_CAP_DRIVER_DISCONNECT,DeviceID, 0 );
            // 关闭窗口
            DestroyWindow(hHwnd);
        }
         #endregion

         #region保存图片
 ///  <  摘要 > 
 /// 允许您将图像以Bmp类型保存到本地计算机
 ///  <  /summary  > 
 公共  void  SaveImage()
        {
            IDataObject数据;
            图片oImage;
            SaveFileDialog saveImage =  SaveFileDialog();
            saveImage.Filter = " ;
            // 将图像复制到剪贴板
            SendMessage(hHwnd,WM_CAP_EDIT_COPY, 0  0 );

            // 从剪贴板获取图像并将其转换为位图
            数据= Clipboard.GetDataObject();
            如果(data.GetDataPresent( typeof (System.Drawing.Bitmap)))
            {
                oImage =(Image)data.GetData( typeof (System.Drawing.Bitmap));
                Container.Image = oImage;
                CloseConnection();
                如果(saveImage.ShowDialog()== DialogResult.OK)
                {
                    oImage.Save(saveImage.FileName,System.Drawing.Imaging.ImageFormat.Bmp);
                }
            }
        }
         #endregion

         #region处置方法
 ///  <  摘要 > 
 /// 关闭与设备的连接并转储所有剩余的内存使用量
 ///  <  /summary  > 
 公共  void  Dispose()
        {
            CloseConnection();
        }
         #endregion
} 

解决方案

是否有您不想使用DirectShow的特殊原因?


Hi, I wanted to know if there is a way of getting my integrated webcam to work without using an external DLL such as directshow etc... I have found some code online, but some the device id is not getting set or it requires external references. The following uses a System 32 API call but device ID remains blank, not to sure how to set it!

class WebCamera : IDisposable
    {
        #region Constants
        /// <summary>
        /// Constants are used to overload unmanaged code functions
        /// Each Constant represents a state
        /// </summary>
        private const short WM_CAP = 0x400;
        private const int WM_CAP_DRIVER_CONNECT = 0x40a;
        private const int WM_CAP_DRIVER_DISCONNECT = 0x40b;
        private const int WM_CAP_EDIT_COPY = 0x41e;
        private const int WM_CAP_SET_PREVIEW = 0x432;
        private const int WM_CAP_SET_OVERLAY = 0x433;
        private const int WM_CAP_SET_PREVIEWRATE = 0x434;
        private const int WM_CAP_SET_SCALE = 0x435;
        private const int WS_CHILD = 0x40000000;
        private const int WS_VISIBLE = 0x10000000;
        private const short SWP_NOMOVE = 0x2;
        private short SWP_NOZORDER = 0x4;
        private short HWND_BOTTOM = 1;
        #endregion

        #region DLLs and properties
        /// <summary>
        /// DllImport allows you to import dlls on the system for your code to cominicate with
        /// This function enables enumerate of WebCam devices
        /// </summary>
        [DllImport("avicap32.dll")]
        protected static extern bool capGetDriverDescriptionA(short wDriverIndex,
                                                              [MarshalAs(UnmanagedType.VBByRefStr)] ref String IpszName,
                                                              int cbName, [MarshalAs(UnmanagedType.VBByRefStr)] ref String IpszVer, int cbVer);
        /// <summary>
        /// DllImport allows you to import dlls on the system for your code to cominicate with
        /// Creates a window child, so that you can display it in a PictureBox
        /// </summary>
        [DllImport("avicap32.dll")]
        protected static extern int capCreateCaptureWindowA([MarshalAs(UnmanagedType.VBByRefStr)] ref string lpszWindowName,
                                                            int dwStyle, int x, int y, int nWidth, int nHeight, int hWndParent, int nID);

        /// <summary>
        /// DllImport allows you to import dlls on the system for your code to cominicate with
        /// This function enables set changes to the size, position, and Z order of a child window
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="hWndInsertAfter"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="cx"></param>
        /// <param name="cy"></param>
        /// <param name="wFlags"></param>
        /// <returns></returns>
        [DllImport("user32")]
        protected static extern int SetWindowPos(int hwnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags);

        /// <summary>
        /// DllImport allows you to import dlls on the system for your code to cominicate with
        /// This function enables send the specified message to a window or windows
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="wMsg"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        [DllImport("user32", EntryPoint = "SendMessageA")]
        protected static extern int SendMessage(int hwnd, int wMsg, int wParam, [MarshalAs(UnmanagedType.AsAny)] object lParam);

        /// <summary>
        /// DllImport allows you to import dlls on the system for your code to cominicate with
        /// This function enable destroy the window child
        /// </summary>
        /// <param name="hwnd"></param>
        /// <returns></returns>
        [DllImport("user32")]
        protected static extern bool DestroyWindow(int hwnd);

        // Normal device ID
        int DeviceID = 0;
        // Handle Value to preview window
        int hHwnd = 0;
        // The list of devices
        ArrayList ListOfDevices = new ArrayList();
        //Display stream in PictureBox
        public PictureBox Container { get; set; }
        #endregion

        #region Load Method
        // Connects to device.
        /// <summary>
        /// This function is used to load the list of devices
        /// </summary>
        public void Load()
        {
            string Name = String.Empty.PadRight(100);
            string Version = String.Empty.PadRight(100);
            bool EndOfDeviceList = false;
            short index = 0;

            //Load and name all of available devices into ListOfDevices
            do
            {
                //Get Driver Name and Version
                EndOfDeviceList = capGetDriverDescriptionA(index, ref Name, 100, ref Version, 100);
                //
                if (EndOfDeviceList) ListOfDevices.Add(Name.Trim());
                index += 1;
            }
            while (!(EndOfDeviceList == false));
        }
        #endregion

        #region Open Connection
        public void OpenConnection()
        {
            Load();

            string DeviceIndex = Convert.ToString(DeviceID);
            // Setting the Container(PictureBox) to handle the Device
            IntPtr oHandle = Container.Handle;
            {
                MessageBox.Show("Set the container property");
            }

            // Open Preview window in picturebox .
            // Create a child window with capCreateCaptureWindowA so you can display it in a picturebox.
            hHwnd = capCreateCaptureWindowA(ref DeviceIndex, WS_VISIBLE | WS_CHILD, 0, 0, 640, 480, oHandle.ToInt32(), 0);

            // Connect to the device
            if (SendMessage(hHwnd, WM_CAP_DRIVER_CONNECT, DeviceID, 0) != 0)
            {
                // Set the preview scale
                SendMessage(hHwnd, WM_CAP_SET_SCALE, -1, 0);
                // Set the preview rate in terms of milliseconds
                SendMessage(hHwnd, WM_CAP_SET_PREVIEWRATE, 66, 0);
                // Start previewing the image from the camera
                SendMessage(hHwnd, WM_CAP_SET_PREVIEW, -1, 0);
                //Resize window to fit the PictureBox
                SetWindowPos(hHwnd, HWND_BOTTOM, 0, 0, Container.Height, Container.Width, SWP_NOMOVE | SWP_NOZORDER);
            }
            else
            {
                // Close device due to connection error
                DestroyWindow(hHwnd);
            }
        }
        #endregion

        #region Close Connection
        public void CloseConnection()
        {
            SendMessage(hHwnd, WM_CAP_DRIVER_DISCONNECT, DeviceID, 0);
            // Close Window
            DestroyWindow(hHwnd);
        }
        #endregion

        #region Save Image
        /// <summary>
        /// Allows you to save image to local machine as type Bmp
        /// </summary>
        public void SaveImage()
        {
            IDataObject data;
            Image oImage;
            SaveFileDialog saveImage = new SaveFileDialog();
            saveImage.Filter = "(*.bmp)|*.bmp";
            // Copy Image to clipboard
            SendMessage(hHwnd, WM_CAP_EDIT_COPY, 0, 0);

            // Get Image from clipboard and convert it to a bitmap
            data = Clipboard.GetDataObject();
            if (data.GetDataPresent(typeof(System.Drawing.Bitmap)))
            {
                oImage = (Image)data.GetData(typeof(System.Drawing.Bitmap));
                Container.Image = oImage;
                CloseConnection();
                if (saveImage.ShowDialog() == DialogResult.OK)
                {
                    oImage.Save(saveImage.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
                }
            }
        }
        #endregion

        #region Dispose Method
        /// <summary>
        /// Closes the connection to device and dumps all remaining memory usage
        /// </summary>
        public void Dispose()
        {
            CloseConnection();
        }
        #endregion
    }

解决方案

Is there a particular reason that you do not want to use directshow?


这篇关于使用不带DirectShow的网络摄像头.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆