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

C# 呼叫 Windows API 擷取網路攝影機影像串流

     編輯:關於C語言

前言:AVICAP 與 P/Invoke

.NET Framework 未直接提供網路攝影機控制類別,但可透過 P/Invoke 呼叫 Windows 多媒體經典 API —— avicap32.dll(Video for Windows 擷取介面)實現影像擷取與預覽。本文整理完整可執行的 WinForms 範例,展示關鍵步驟與程式碼結構。

核心架構

  1. showVideo:靜態類別,定義所有 P/Invoke 簽名、常數、結構體(BITMAPINFO、VIDEOHDR 等)。
  2. WebCamera:封裝攝影機邏輯,管理視窗建立、驅動程式連線、預覽啟動、影格回呼與資源釋放。
  3. Form1:UI 介面,包含預覽面板、開始/停止按鈕。

關鍵 API 簽名節錄

[DllImport("avicap32.dll")]
public static extern IntPtr capCreateCaptureWindowA(
    byte[] lpszWindowName, int dwStyle, int x, int y,
    int nWidth, int nHeight, IntPtr hWndParent, int nID);

[DllImport("avicap32.dll")]
public static extern bool capGetDriverDescriptionA(
    short wDriver, byte[] lpszName, int cbName,
    byte[] lpszVer, int cbVer);

[DllImport("User32.dll")]
public static extern bool SendMessage(
    IntPtr hWnd, int wMsg, int wParam, ref BITMAPINFO lParam);

影格回呼機制

關鍵在於 WM_CAP_SET_CALLBACK_FRAME 訊息,註冊 FrameEventHandler 委派:

private void FrameCallBack(IntPtr lwnd, IntPtr lpVHdr)
{
    VIDEOHDR videoHeader = (VIDEOHDR)Marshal.PtrToStructure(lpVHdr, typeof(VIDEOHDR));
    byte[] videoData = new byte[videoHeader.dwBytesUsed];
    Marshal.Copy(videoHeader.lpData, videoData, 0, videoData.Length);
    RecievedFrame?.Invoke(videoData); // 觸發事件,傳遞原始位元組陣列
}

啟動流程

public void StartWebCam()
{
    byte[] name = new byte[100], ver = new byte[100];
    capGetDriverDescriptionA(0, name, 100, ver, 100); // 取得第一個裝置資訊

    lwndC = capCreateCaptureWindowA(name, WS_VISIBLE | WS_CHILD, 0, 0,
        mWidth, mHeight, mControlPtr, 0);

    if (capDriverConnect(lwndC, 0))
    {
        capPreviewRate(lwndC, 66);          // 預覽幀率 ~15fps
        capPreview(lwndC, true);            // 開啟預覽
        SetVideoFormat(...);                // 設定 352x288, 24bit
        mFrameEventHandler = new FrameEventHandler(FrameCallBack);
        capSetCallbackOnFrame(lwndC, mFrameEventHandler); // 註冊回呼
        SetWindowPos(lwndC, 0, 0, 0, mWidth, mHeight, SWP_NOMOVE | SWP_NOZORDER);
    }
}

UI 整合

private void Form1_Load(object sender, EventArgs e)
{
    wc = new WebCamera(panelPreview.Handle, panelPreview.Width, panelPreview.Height);
    wc.StartWebCam();
    wc.RecievedFrame += data => {
        // 這裡處理影格資料:顯示、錄製、辨識等
        // 注意:回呼在非 UI 執行緒,跨執行緒更新 UI 需 Invoke
    };
}

注意事項與現代替代方案

  • VFW (avicap32) 已過時:Windows 7+ 建議使用 DirectShow 或 Media Foundation。
  • Managed 封裝庫:AForge.NET、Accord.NET、OpenCvSharp 提供更高階、跨平台的攝影機存取。
  • 記憶體管理:委派實例 mFrameEventHandler 必須保持存活,防止 GC 回收導致回呼失效。
  • 64 位元相容:IntPtr、Marshal 正確處理指標大小,但結構體對齊需謹慎驗證。

結語

雖然 VFW 屬於上一代技術,但透過 P/Invoke 實現攝影機擷取是理解 Windows 多媒體架構、非受控互操作與即時影像處理管線的絕佳練習。實務專案請優先採用現代函式庫。

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