這篇文章分享使用.Net 玩單反
背景
#一年多沒逛園子了,換了個行業圈子,感覺自己太花心了點,不過能接觸到不同的研發文化也算有點收穫,遊戲圈的技術流、電商圈的業務流、媒體圈的藝術流等等。
這個應用程式產生的背景是讓單眼相機自動化,本身老大的意思是想做針對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,Canonsdk .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方法開啟的是多線程但是硬碟本身是串列的這裡只是寫著玩大家不用認真
效果圖
新加入相機裝置
程式控制相機拍照
本機載入相機內照片資料
#
以上是.Net 玩單眼的技巧的詳細內容。更多資訊請關注PHP中文網其他相關文章!