.NET Framework 未直接提供網路攝影機控制類別,但可透過 P/Invoke 呼叫 Windows 多媒體經典 API —— avicap32.dll(Video for Windows 擷取介面)實現影像擷取與預覽。本文整理完整可執行的 WinForms 範例,展示關鍵步驟與程式碼結構。
BITMAPINFO、VIDEOHDR 等)。[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);
}
}
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
};
}
AForge.NET、Accord.NET、OpenCvSharp 提供更高階、跨平台的攝影機存取。mFrameEventHandler 必須保持存活,防止 GC 回收導致回呼失效。IntPtr、Marshal 正確處理指標大小,但結構體對齊需謹慎驗證。雖然 VFW 屬於上一代技術,但透過 P/Invoke 實現攝影機擷取是理解 Windows 多媒體架構、非受控互操作與即時影像處理管線的絕佳練習。實務專案請優先採用現代函式庫。