首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

.NET 實現單眼相機自動化控制:Canon SDK 與 WIA 介面應用

     編輯:關於.NET

專案需求:多台 Canon 單眼相機透過 USB 連接電腦,定時拍照並自動上傳。本文比較 Canon SDK 與 Windows Image Acquisition (WIA) 兩種介面,分享 WIA 列舉裝置、下載影像、SDK 事件處理的完整代碼。

技術選型比較

維度Canon EOS SDKWIA (Windows Image Acquisition)
支援型號僅 Canon 相容機種所有符合 WIA 標準的影像裝置 (掃描儀、Webcam、相機)
功能深度完整控制:快門、光圈、ISO、對焦、Live View基礎操作:拍照、下載、屬性讀寫
.NET 整合官方提供 .NET Wrapper (EDSDK.dll)系統內建 COM 元件,直接加參考
取得裝置內檔案.NET 版 SDK **缺乏** 列舉/下載 API原生支援列舉裝置儲存區、下載檔案
適用場景需精細控制相機參數的專業應用通用影像採集、多品牌裝置、簡單拍照下載

專案最終採用 **WIA** 解決「多裝置自動下載」,輔以 SDK 處理「拍攝觸發與參數設定」。

WIA 核心概念

  • Device Manager:列舉裝置、建立裝置連線
  • Device:代表實體裝置,含屬性、命令、事件
  • Item:裝置儲存區中的單一項目 (資料夾/檔案)
  • IWiaDataTransfer:高效能共享記憶體傳輸介面

列舉並連接所有相機裝置

using WIA; // 需加入 COM 參考 "Microsoft Windows Image Acquisition Library v2.0"

public class CameraManager
{
    private readonly DeviceManager _deviceManager = new DeviceManagerClass();

    public IEnumerable GetCameraDevices()
    {
        foreach (DeviceInfo info in _deviceManager.DeviceInfos)
        {
            if (info.Type == WiaDeviceType.CameraDeviceType)
                yield return info;
        }
    }

    public void DownloadAllImages(Action onFileDownloaded)
    {
        int index = 1;
        foreach (var info in GetCameraDevices())
        {
            var device = info.Connect();
            var param = new CameraParam { Device = device, DeviceId = info.DeviceID, Index = index++ };
            
            // 非同步下載避免阻塞 UI
            Task.Run(() => DownloadFromCamera(param, onFileDownloaded));
        }
    }

    private void DownloadFromCamera(CameraParam param, Action callback)
    {
        try
        {
            // 遍歷儲存區項目
            foreach (Item item in param.Device.Items)
            {
                if (item.IsFolder)
                {
                    DownloadFromFolder(item, param, callback); // 遞迴處理資料夾
                }
                else
                {
                    DownloadItem(item, param, callback);
                }
            }
        }
        catch (Exception ex)
        {
            // 記錄錯誤
        }
    }

    private void DownloadFromFolder(Item folder, CameraParam param, Action callback)
    {
        foreach (Item item in folder.Items)
        {
            if (item.IsFolder) DownloadFromFolder(item, param, callback);
            else DownloadItem(item, param, callback);
        }
    }

    private void DownloadItem(Item item, CameraParam param, Action callback)
    {
        string tempPath = Path.Combine(Path.GetTempPath(), $"Cam{param.Index}_{item.Name}");
        var transfer = (IWiaDataTransfer)item.Transfer(WIA.FormatID.wiaFormatJPEG, false);
        transfer.GetData(out object data);
        File.WriteAllBytes(tempPath, (byte[])data);
        callback?.Invoke(param.DeviceId, tempPath);
    }
}

public class CameraParam
{
    public Device Device { get; set; }
    public string DeviceId { get; set; }
    public int Index { get; set; }
}

Canon SDK 事件處理 (補充)

.NET 版 SDK 提供 5 種委託回呼:

public delegate uint EdsProgressCallback(uint percent, IntPtr context, ref bool cancel);
public delegate uint EdsCameraAddedHandler(IntPtr context);
public delegate uint EdsPropertyEventHandler(uint eventId, uint propertyId, uint param, IntPtr context);
public delegate uint EdsObjectEventHandler(uint eventId, IntPtr objectRef, IntPtr context);
public delegate uint EdsStateEventHandler(uint eventId, uint param, IntPtr context);

典型用法:偵測相機新增檔案並自動下載

// 註冊事件
_camera.SetObjectEventHandler(EdsObjectEventHandler, IntPtr.Zero);
_camera.SetPropertyEventHandler(EdsPropertyEventHandler, IntPtr.Zero);

// 回呼實作
private uint OnObjectEvent(uint eventId, IntPtr objRef, IntPtr context)
{
    if (eventId == EDSDK.ObjectEvent_DirItemCreated) // 新檔案建立
    {
        // 取得檔案資訊並下載
        DownloadFile(objRef);
    }
    return EDSDK.EDS_ERR_OK;
}

裝置類型辨識補充

USB 介面類別碼 (`bInterfaceClass`) 決定裝置在系統中的呈現:

  • `06` (Image) - 掃描儀、Webcam、部分相機 → 可被 WIA 列舉
  • `08` (Mass Storage) - 大多數相機、隨身碟 → 磁碟機代號,`DriveInfo.GetDrives()` 可見
  • Canon 單眼通常同時支援兩種介面,**WIA 走 Image 介面,SDK 走 Vendor Specific 介面**

若 `DriveInfo` 看不到相機,請嘗試 WIA `DeviceManager` 列舉 `CameraDeviceType`。

完整流程整合

  1. 啟動服務,掃描 WIA 相機裝置
  2. 定時器觸發 (如每 30 秒) → 呼叫 Canon SDK 發送拍照命令
  3. SDK `ObjectEvent` 回呼偵測新檔案 → 下載至暫存
  4. 上傳至伺服器/微博 API
  5. 清理暫存檔

原始碼專案包含 WIA 封裝類、SDK 事件綁定、定時排程、上傳模組,歡迎參考擴充。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved