zoukankan      html  css  js  c++  java
  • .Net 玩单反

    就如标题所示了 源码地址 https://github.com/dubing/CannonSDKandWia/


    背景

    一年多没逛园子了,换了个行业圈子,感觉自己太花心了点,不过能接触到不同的研发文化也算有点收获,游戏圈子的技术流、电商圈子的业务流、媒体圈子的艺术流等等。

    这个应用产生的背景是让单反相机自动化,本身老大的意思是想做针对usb接口的编程,不过太底层的技术用c#来做不是很合适。讨价还价了一番,那就针对单反来做吧。

    假设一个场景,我们需要N台单反设备瞄准一朵花,每隔30秒拍一张照片并且自动发到微博上。


    技术点

      佳能SDK  

      WIA标准

      佳能sdk提供了dll给.net开发者引用,通过对sdk的调用可以方便的佳能对应型号的相机,不过对于获取相机内的数据.net版本 sdk中并没有提供。那么如何获取单反相机内的数据就成了一个问题点。有些同学可能会疑惑,单反相机接入电脑usb插口不就会产生一个盘符么,直接用DriveInfo.GetDrives()获取盘符遍历不就可以了么。这里先给大家扫盲一下,USB从设备的分类可以从USB设备接口描述符对应的的bInterfaceClass这一个byte得到。 bInterfaceClass的典型代码为1,2,3,6,7,8,9,10,11,255。分别代表意思为1-audio:表示一个音频设 备。2-communication device:通讯设备,如电话,moden等等。3-HID:人机交互设备,如键盘,鼠标等。6-image图象设备,如扫描仪,摄像头等,有时数码相 机也可归到这一类。7-打印机类。如单向,双向打印机等。8-mass storage海量存储类。所有带有一定存储功能的都可以归到这一类。如数码相机大多数都归这一类。9-hub类。11-chip card/smart card。255-vendor specific.厂家的自定义类,主要用于一些特殊的设备。如接口转接卡等。

      我们的driveinfo可以捕捉的设备类型为

    public enum DriveType
        {
            // Summary:
            //     The type of drive is unknown.
            Unknown = 0,
            //
            // Summary:
            //     The drive does not have a root directory.
            NoRootDirectory = 1,
            //
            // Summary:
            //     The drive is a removable storage device, such as a floppy disk drive or a
            //     USB flash drive.
            Removable = 2,
            //
            // Summary:
            //     The drive is a fixed disk.
            Fixed = 3,
            //
            // Summary:
            //     The drive is a network drive.
            Network = 4,
            //
            // Summary:
            //     The drive is an optical disc device, such as a CD or DVD-ROM.
            CDRom = 5,
            //
            // Summary:
            //     The drive is a RAM disk.
            Ram = 6,
        }
    

       一般u盘设备都是Removable的,但是单反相机是PortableDevice,用GetDrives方法是获取不到这种类型的。在windows systems32中提供了一系列针对portabledevice的api方法有兴趣的同学可以尝试下

      这里我选择的是wia接口编程,WIA 是 Windows Image Acquisition 的简称,当前可用版本是 WIA 1.0,它是 Windows Millennium Edition (Windows Me) 或者更高版本的 Windows 系统中提供的数字图像获取服务,同时它也能用于管理数字图像设备。WIA 是使用进程外(Out of process)服务实现的 COM 组件,和大多数进程外服务程序不同的是,WIA 通过提供自己的数据传送机制(IWiaDataTransfer 接口),避免了图像数据传送过程中的性能损失。高性能的 IWiaDataTransfer 接口使用共享内存来传送数据给客户程序。
    WIA 有三个主要的组件:Device Manager,Minidriver Service Library 和 Device Minidriver。
    ◆Device Manager: 枚举图像设备,获取设备属,为设备建立事件和创建设备对象;
    ◆Minidriver Service Library: 执行所有设备无关的服务;
    ◆Device Minidriver 解释映射: WIA 属性和命令到特定的设备。
    通过DeviceManagerClass().DeviceInfos中的信息 我们可以采集到单反中有属于CameraDeviceType的设备信息,至于视频等其他类型有其他类似方法。

            public void DownJpgFromAllCamera()
            {
                int i = 1;
                foreach (IDeviceInfo DevInfo in new DeviceManagerClass().DeviceInfos)
                {
                    if (DevInfo.Type == WiaDeviceType.CameraDeviceType)
                    {
                        string DeviceID = DevInfo.DeviceID;
                        Device wDevice = DevInfo.Connect();
                        Devparam dev = new Devparam {wiaDevice=wDevice, DeviceID = DeviceID, index = i };
                        new Thread((Camera) => 
                            {
                                DownJpg(((Devparam)Camera).wiaDevice, ((Devparam)Camera).DeviceID, ((Devparam)Camera).index);
                            }
                            ).Start(dev);
                     
                      
                        i++;
                    }
                }
            }
    

       再来谈谈SDK,佳能sdk .net版本中提供5种句柄委托

            public delegate uint EdsProgressCallback( uint inPercent, IntPtr inContext, ref bool outCancel);
            public delegate uint EdsCameraAddedHandler(IntPtr inContext);
            public delegate uint EdsPropertyEventHandler(uint inEvent, uint inPropertyId, uint inParam, IntPtr inContext); 
            public delegate uint EdsObjectEventHandler( uint inEvent, IntPtr inRef, IntPtr inContext); 
            public delegate uint EdsStateEventHandler( uint inEvent, uint inParameter, IntPtr inContext);
    

    第一个用于数据处理过程例如数据复制、图片保存等。

    第二个用于pc发现新的相机设备

    第三个用于相机内数据流等属性状态变化通知,例如拍照动作产生的系列变化

    第四个用于文件操作 例如文件创建 删除等等

    第五个用于相机自身的状态时间 例如开关机 异常等

    各种应用的场景大家参看下demo程序 虽然load方法开启的是多线程 但是硬盘io本身是串行的 这里只是写着玩 大家不用认真


    效果图

      新添加相机设备

    程序控制相机拍照

    本地加载相机内照片数据


    题外话

    程序只是demo,调查兼娱乐。有bug是肯定的,sdk的dll请大家下载最新的参考api文档。源码程序参考页首

    原创作品允许转载,转载时请务必以超链接形式标明文章原始出处以及作者信息。
    作者:熬夜的虫子
    点击查看:博文索引
  • 相关阅读:
    Web 日志分析过程
    nginx系列之九:lua服务
    Linux网络编程之IO模型
    从URL输入到页面展现到底发生什么
    CentOS 日常运维十大技能
    以MySQL为例,详解数据库索引原理(1)
    Elasticsearch的特点以及应用场景
    Ubuntu1804编译安装LNMP
    golang 高级
    Centos7 安装 Redis
  • 原文地址:https://www.cnblogs.com/dubing/p/2970984.html
Copyright © 2011-2022 走看看