Welcome

首页 / 软件开发 / .NET编程技术 / .Net实现单反效果

.Net实现单反效果2015-12-29 熬夜的虫子 背景

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

这个应用产生的背景是让单反相机自动化,本身老大的意思是想做针对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++;}}}