WPF中使用DirectShowLib枚举摄像头设备和分辨率



提供window平台下基于Net技术和Qt技术的多点触摸设备应用开发,画板开发,摄像头/展台设备应用开发



本质还是对DX接口的运用,直接代码好理解

1. 定义设备接口

public interface IDevice{
    string DeviceName{get;set;}  //设备名称
    string DevicePath{get;set;}  //设备路径
    System.Runtime.InteropServices.ComTypes.IMoniker Moniker{get;set;}
}

2.展台设备接口

public class CameraDevice : IDevice{
    // - interface IDevice -
    public string DeviceName{get;set;}
    public string DevicePath{ get; set; }
    public System.Runtime.InteropServices.ComTypes.IMoniker Moniker{get;set;}
    // end IDevice

    //分辨率结构体
    public struct Resolution{
        public double Width{set;set;}
        public double Height{get;set;}
    }

    public CameraDevice(){
        this.DevicePath = string.Empty;
        this.DeviceName = string.Empty;
    }
}

3. 服务类,实现利用DirectShowLib获取设备的分辨率,本质还是DX接口的运用

public class DeviceService
{
    // 获取系统内安装的视频输入设备~
    public System.Collections.Generic.IList<IDevice> GetDevices()
    {
        DsDevice[] devicesOfCat = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
        System.Collections.Generic.IList<IDeviceInfo> list = new System.Collections.Generic.List<IDeviceInfo>();
        DsDevice[] array = devicesOfCat;

        for( int i  = 0 ; i < array.length ; i++ ){
            DsDevice dsdevice = array[i];
            list.Add({new CameraDevice{
                DeviceName = dsdevice.Name,
                DevicePath = dsdevice.DevicePath,
                Moniker  = dsdevice.Mon
            }});
        }

        return list;
    }

    public System.Collections.Generic.IList<CameraDevice.Resolution> GetResolutions(string devicePath)
    {
        //获取设备
        System.Collections.Generic.IList<IDevice> devices= this.GetDevices();
        foreach( IDevice current in devices)
        {
            //获取当前指定设备路径的关联分辨率
            if( current.DevicePath == devicePath ){
                return this.GetResolutions(current);
            }
        }

        return new System.Collections.Generic.List<CameraDevice.Resolution>();
    }

 private System.Collections.Generic.IList<CameraDevice.Resolution> GetResolutions(IDevice deivce)
 {
     System.Collections.Generic.List<CameraDevice.Resolution> list = new System.Collections.Generic.List<CameraDevice.Resolution>();
     IBaseFilter vSource = null;
    IFilterGraph2 filterGraph = new FilterGraph() as IFilterGraph2;
    if (filterGraph == null)
     {
          return list;
     }
     filterGraph.AddSourceFilterForMoniker(deivce.Moniker, null, deivce.DeviceName, out vSource);
     IPin pin = DsFindPin.ByCategory(vSource, PinCategory.Capture, 0);
     VideoInfoHeader videoInfoHeader = new VideoInfoHeader();
     IEnumMediaTypes enumMediaTypes;
     pin.EnumMediaTypes(out enumMediaTypes);
     AMMediaType[] array = new AMMediaType[1];
     System.IntPtr zero = System.IntPtr.Zero;
     enumMediaTypes.Next(1, array, zero);
     int num = 0;
     int num2 = 0;
     while (array.Any<AMMediaType>() && array[0] != null)
     {
        System.Runtime.InteropServices.Marshal.PtrToStructure(array[0].formatPtr, videoInfoHeader);
        if (videoInfoHeader.BmiHeader.Size != 0 && videoInfoHeader.BmiHeader.BitCount != 0)
         {
            if ((int)videoInfoHeader.BmiHeader.BitCount > num2)
            {
                list.Clear();
                num = 0;
                num2 = (int)videoInfoHeader.BmiHeader.BitCount;
            }

            list.Add(new CameraDevice.Resolution
            {
                Width = (double)videoInfoHeader.BmiHeader.Width,
                Height = (double)videoInfoHeader.BmiHeader.Height
            });

            if (videoInfoHeader.BmiHeader.Width > num || videoInfoHeader.BmiHeader.Height > num)
            {
                num = System.Math.Max(videoInfoHeader.BmiHeader.Width, videoInfoHeader.BmiHeader.Height);
            }
         }
         enumMediaTypes.Next(1, array, zero);
     } 

     return (from d in list.Distinct<CameraDevice.Resolution>()
                    orderby d.Width
                    select d).ToList<CameraDevice.Resolution>();
  }
}

4. 测试:新建WPF工程,一个按钮。 click事件

private void _btnGetDevices_Click_1(object sender, RoutedEventArgs e)
 {
            DeviceService videoservice = new DeviceService();
            IList<IDevice> deviceinfos = videoservice.GetDevices();
            if (deviceinfos != null && deviceinfos.Count > 0)
            {
                IDevice d = deviceinfos[0];
                List<CameraDevice.Resolution> ls = videoservice.GetResolutions(d).ToList<CameraDevice.Resolution>();
                string strmsg = string.Empty;
                strmsg += "device count:" + deviceinfos.Count.ToString() + "\n";
                strmsg += "device name:" + d.DeviceName + "\n";
                foreach (CameraDevice.Resolution cur in ls)
                {
                    strmsg += "RW:" + cur.Width + " ; RH: " + cur.Height + "\n";
                }

                MessageBox.Show(strmsg);
            }
}



WPF中使用DirectShowLib枚举摄像头设备和分辨率

时间: 2024-10-11 05:51:16

WPF中使用DirectShowLib枚举摄像头设备和分辨率的相关文章

在WPF中使用变通方法实现枚举类型的XAML绑定

问题缘起 WPF的分层结构为编程带来了极大便利,XAML绑定是其最主要的特征.在使用绑定的过程中,大家都普遍的发现枚举成员的绑定是个问题.一般来说,枚举绑定多出现于与ComboBox配合的情况,此时我们希望实现的目标有: 建立选择项与ItemsSource的对应关系: 自动获取用于ItemsSource的枚举源: 自定义下拉框中显示的内容. 对于目标1,考虑最简单的模式,即枚举的定义采用从0开始的连续整数,可以使用IValueConverter接口来实现从枚举到整型的双向转换,以使得枚举成员绑定

在WPF中使用AForge.net控制摄像头拍照

原文:在WPF中使用AForge.net控制摄像头拍照 利用AForge.net控制摄像头拍照最方便的方法就是利用PictureBox显示摄像头画面,但在WPF中不能直接使用PictureBox.必须通过<WindowsFormsHost></WindowsFormsHost>来提供交换功能.其解决方法如下: 1.按照常规方法新建一个WPF应用程序: 2.添加引用 WindowsFormsIntegration  (与WinForm交互的支持) System.Windows.For

在WPF中开启摄像头扫描二维码(Media+Zxing)

原文:在WPF中开启摄像头扫描二维码(Media+Zxing) 近两天项目中需要添加一个功能,是根据摄像头来读取二维码信息,然后根据读出来的信息来和数据库中进行对比显示数据. 选择技术Zxing.WPFMediaKit.基本的原理就是让WPFmediaKit来对摄像头进行操作,然后Zxing这个库对图片进行分析大致就是这样. 在后台中定义了定时器,用于解析当前摄像头的图像,然后直接读数据. 需要注意的是一定要引入 using WPFMediaKit.DirectShow.Controls; us

WPF中实现拍照功能(利用“WPFMediaKit.dll”)

开始先展示下效果图: -------------------------------下面记录步骤:------------------------------------------------------ 下载“WPFMediaKit.dll”程序开发包,用在项目中添加引用: 在WPF窗口引入并命名: xmlns:wpfMedia="clr-namespace:WPFMediaKit.DirectShow.Controls;assembly=WPFMediaKit" 在界面用到一个V

WPF中的瀑布流布局(TilePanel)控件

最近在用wpf做一个metro风格的程序,需要用到win8风格的布局容器,只能自己写一个了.效果如下 用法 : <local:TilePanel                          TileMargin="1"                         Orientation="Horizontal"                         TileCount="4" > //todo 放置内容 //loc

WPF中实现先登录后启动主程序的方法

[转载] http://blog.csdn.net/swarb/article/details/17301167 WPF中实现先登录后启动主程序的方法 我觉得先登录后启动应用主程序是一个很经典的问题,基本上如果要写一个应用程序都会用到这个的小环节.我在这个问题上挣扎了大半天才找到解决方案,我的实现方法我觉得有点不正宗,如果有哪位高手知道更好的方法欢迎留言指导!! 首先来说一下传统C#在WinForm中的实现方法,基本上是在Main函数中根据第一个启动窗口的DialogResult来判断是否实例第

WPF中DPI的问题

先搞清楚一下几个概念: DPI:dots  per  inch ,每英寸的点数.我们常说的鼠标DPI,是指鼠标移动一英寸的距离滑过的点数:打印DPI,每英寸的长度打印的点数:扫描DPI,每英寸扫描了多少个点.(更多请参考百度百科http://baike.baidu.com/view/49853.htm) 像素:pixel,picute和element的缩写.像素可以简单的理解为DPI里面的点.例如,显示器的分辨率为1024像素*768像素,就是说显示器的横向可显示1024个点(像素),纵向科研可

再论WPF中的UseLayoutRounding和SnapsToDevicePixels

以下摘自: http://blog.csdn.net/muzizongheng/article/details/14163227    的博客: 再论WPF中的UseLayoutRounding和SnapsToDevicePixels 分类:             自我心的              2013-11-05 11:16     732人阅读     评论(0)     收藏     举报 wpf自我心的UseLayoutRoundingGridSplitter模糊 最近在调试项目

枚举硬件设备

下载源码:http://dl2.csdn.net/down4/20070627/27161251844.rar HOWTO: 通过使用 SetupDi 调用函数枚举硬件设备 察看本文应用于的产品 文章编号 : 259695 最后修改 : 2004年3月10日 修订 : 2.0 本文的发布号曾为 CHS259695 概要 要得到 Windows 2000 中安装的硬件设备列表,应用程序可以调用 SetupDi 类 API 函数. 回到顶端 更多信息 以下代码段演示如何显示已经安装的所有硬件设备的列