C#调用avicap32.dll实现摄像头拍照与二维码识别

程一诺
程一诺
发布时间:2026-10-16| 7人浏览过
原创

在C#开发中,若需在WinForms桌面应用中调用本地摄像头进行图像采集或二维码识别,可以使用系统底层的 avicap32.dll 库。本文将详细拆解如何初始化摄像头、获取预览、保存截屏以及使用 ZXing 库解码二维码的完整流程。

核心逻辑说明

该方案主要包含三个部分:一是通过 Windows 媒体控制接口连接摄像头并显示预览;二是截取当前视频帧保存为 BMP 文件;三是读取该文件利用 ZXing.Net 库解析二维码文本。需要注意的是,avicap32 是较老的API,通常用于传统的WinForms控件宿主环境,不直接支持现代浏览器端或无界面(Headless)服务器环境。

1. 初始化与声明

首先需要在类中声明外部 DLL 函数及相关的常量。这一步定义了摄像头窗口的创建参数和视频消息的控制指令。

// 定义必要的常量
private const int WM_USER = 0x400;
private const int WS_CHILD = 0x40000000;
private const int WS_VISIBLE = 0x10000000;
private const int WM_CAP_START = WM_USER;
// ... 其他 WM_CAP_ 相关常量 ...

// 引入外部动态链接库
[DllImport("avicap32.dll")]
private static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID);

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

2. 启动摄像头预览

创建一个控制类 Pick,在 Start() 方法中建立与摄像头的连接。此过程会创建一个子窗口用于实时显示摄像头画面。

public void Start()
{
    if (bStat) return;
    bStat = true;
    byte[] lpszName = new byte[100];

    // 创建捕获窗口
    hWndC = capCreateCaptureWindowA(lpszName, WS_CHILD | WS_VISIBLE, mLeft, mTop, mWidth, mHeight, mControlPtr, 0);

    if (hWndC.ToInt32() != 0)
    {
        // 设置回调和连接设备
        SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);
        SendMessage(hWndC, WM_CAP_SET_SCALE, 1, 0);
        SendMessage(hWndC, WM_CAP_SET_PREVIEWRATE, 66, 0);
        SendMessage(hWndC, WM_CAP_SET_PREVIEW, 1, 0);
    }
}

3. 执行抓拍与录像操作

抓取图像的核心是将当前视频缓冲区的数据保存为磁盘上的 BMP 文件。这是后续二维码识别的基础步骤。

/// <summary>
/// 抓图保存到指定路径
/// </summary>
public void GrabImage(string path)
{
    IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);
    SendMessage(hWndC, WM_CAP_SAVEDIB, 0, hBmp.ToInt64());
}

4. 完整集成示例与二维码解码

以下代码展示了如何在 WinForms 页面中实例化摄像头控制对象,抓取一张图片,并使用 ZXing.Net 库读取其中的二维码信息。请确保项目中已安装 ZXing.Net NuGet 包。

using System;
using System.Windows.Forms;
using System.Drawing;
using ZXing;

public partial class FormCamera : Form
{
    public class Pick
    {
        private const int WM_USER = 0x400;
        private const int WS_CHILD = 0x40000000;
        private const int WS_VISIBLE = 0x10000000;
        private const int WM_CAP_START = WM_USER;
        private const int WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10;
        private const int WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11;
        private const int WM_CAP_SAVEDIB = WM_CAP_START + 25;
        private const int WM_CAP_SET_OVERLAY = WM_CAP_START + 51;
        private const int WM_CAP_SET_PREVIEW = WM_CAP_START + 50;
        private const int WM_CAP_SET_SCALE = WM_CAP_START + 53;
        private const int WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52;

        private IntPtr hWndC;
        private bool bStat = false;
        private IntPtr mControlPtr;
        private int mWidth, mHeight, mLeft, mTop;

        public Pick(IntPtr handle, int left, int top, int width, int height)
        {
            mControlPtr = handle; mWidth = width; mHeight = height;
            mLeft = left; mTop = top;
        }

        [System.Runtime.InteropServices.DllImport("avicap32.dll")]
        private static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID);
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        private static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, long lParam);

        public void Start()
        {
            if (bStat) return;
            bStat = true;
            byte[] lpszName = new byte[100];
            hWndC = capCreateCaptureWindowA(lpszName, WS_CHILD | WS_VISIBLE, mLeft, mTop, mWidth, mHeight, mControlPtr, 0);
            if (hWndC.ToInt32() != 0)
            {
                SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);
                SendMessage(hWndC, WM_CAP_SET_SCALE, 1, 0);
                SendMessage(hWndC, WM_CAP_SET_PREVIEWRATE, 66, 0);
                SendMessage(hWndC, WM_CAP_SET_PREVIEW, 1, 0);
            }
        }
        public void Stop()
        {
            SendMessage(hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0);
            bStat = false;
        }
        public void GrabImage(string path)
        {
            IntPtr hBmp = System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(path);
            SendMessage(hWndC, WM_CAP_SAVEDIB, 0, hBmp.ToInt64());
        }
    }

    private void btnCapture_Click(object sender, EventArgs e)
    {
        try
        {
            // 1. 准备UI容器
            using (var frm = new Form())
            using (var panel = new PictureBox { Height = 300, Width = 300, Visible = true, BackgroundImageLayout = ImageLayout.None })
            {
                frm.Controls.Add(panel);
                frm.TopMost = true;

                // 2. 初始化并启动摄像头
                var pick = new Pick(panel.Handle, 0, 0, 300, 300);
                pick.Start();

                // 3. 执行抓拍
                string savePath = System.IO.Path.Combine(Application.StartupPath, "capture.bmp");
                pick.GrabImage(savePath);

                // 4. 停止资源
                pick.Stop();
            }

            // 5. 使用 ZXing 解码
            if (System.IO.File.Exists(savePath))
            {
                Bitmap bmp = new Bitmap(savePath);
                var reader = new BarcodeReader();
                var result = reader.Decode(bmp);

                if (result != null)
                {
                    MessageBox.Show("识别结果: " + result.Text);
                }
                else
                {
                    MessageBox.Show("未检测到有效二维码");
                }
                bmp.Dispose();
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("发生错误: " + ex.Message);
        }
    }
}

关键注意事项

  • 运行环境: avicap32 依赖于 Windows 系统的摄像头驱动框架,且必须在具有 GUI 线程模型的进程中运行(如 WinForms/WPF),无法在无头服务中直接使用。
  • 依赖库: 本例使用了 ZXing.Net 进行条码解析,请在 NuGet 管理器中搜索安装该库。
  • 权限与安全: 调用摄像头通常需要用户确认,首次运行时可能会弹出隐私授权提示。

以上就是C#利用avicap32库调用摄像头拍照并结合ZXing进行二维码识别的详细内容,更多关于C#硬件交互控制的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。