【问题标题】:How do I capture video from a webcam?如何从网络摄像头捕获视频?
【发布时间】:2011-02-10 04:00:19
【问题描述】:

我需要从网络摄像头捕捉视频。 C#/.NET 中是否有任何类可以帮助我解决这个问题。我只对实时数据感兴趣。

有没有什么好的 C#/.NET 书籍可供我学习以深入了解该语言和平台?

【问题讨论】:

  • 欢迎来到 StackOverflow。我建议您注册一个帐户,这样您就可以始终如一地跟踪您的问题。这是一个很好的问题,但你在这里问了两个问题。你能把第二个问题变成一个新问题吗?我认为您实际上可以在这里找到您想要的答案:The Definitive C++ Book Guide and List 但我会毫不犹豫地问这是否对您有帮助。应该可以的。
  • 我建议您将问题分成两部分:网络摄像头部分和书籍部分。
  • @drachenstern:怀疑他会在一本关于 C++ 的书中找到他的 C# 问题的答案。不过我想这是可能的。
  • @CodyGray 你是对的,我从我的意思中抓住了错误的臭链接:\ ...而你只迟到了 50 分钟让我在 5 分钟的窗口中更正它;)@ 987654322@
  • 这是关于网络摄像头的许多其他问题的重复,例如:stackoverflow.com/questions/233455/webcam-usage-in-c 我不知道如何正确报告此问题,抱歉。

标签: c# .net


【解决方案1】:

这是我使用的。 您需要一流的设备来迭代您的设备:

public class DeviceManager
{
    [DllImport("avicap32.dll")]
    protected static extern bool capGetDriverDescriptionA(short wDriverIndex,
        [MarshalAs(UnmanagedType.VBByRefStr)]ref String lpszName,
       int cbName, [MarshalAs(UnmanagedType.VBByRefStr)] ref String lpszVer, int cbVer);

    static ArrayList devices = new ArrayList();

    public static TCamDevice[] GetAllDevices()
    {
        String dName = "".PadRight(100);
        String dVersion = "".PadRight(100);

        for (short i = 0; i < 10; i++)
        {
            if (capGetDriverDescriptionA(i, ref dName, 100, ref dVersion, 100))
            {
                TCamDevice d = new TCamDevice(i);
                d.Name = dName.Trim();
                d.Version = dVersion.Trim();

                devices.Add(d);
            }
        }

        return (TCamDevice[])devices.ToArray(typeof(TCamDevice));
    }

    public static TCamDevice GetDevice(int deviceIndex)
    {
        return (TCamDevice)devices[deviceIndex];
    }
}

还有这个来控制凸轮。

public class TCamDevice
{
     private const short WM_CAP = 0x400;
    private const int WM_CAP_DRIVER_CONNECT = 0x40a;
    private const int WM_CAP_DRIVER_DISCONNECT = 0x40b;
    private const int WM_CAP_EDIT_COPY = 0x41e;
    private const int WM_CAP_SET_PREVIEW = 0x432;
    private const int WM_CAP_SET_OVERLAY = 0x433;
    private const int WM_CAP_SET_PREVIEWRATE = 0x434;
    private const int WM_CAP_SET_SCALE = 0x435;
    private const int WS_CHILD = 0x40000000;
    private const int WS_VISIBLE = 0x10000000;

    [DllImport("avicap32.dll")]
    protected static extern int capCreateCaptureWindowA([MarshalAs(UnmanagedType.VBByRefStr)] ref string lpszWindowName,
        int dwStyle, int x, int y, int nWidth, int nHeight, int hWndParent, int nID);

    [DllImport("user32", EntryPoint = "SendMessageA")]
    protected static extern int SendMessage(int hwnd, int wMsg, int wParam, [MarshalAs(UnmanagedType.AsAny)] object lParam);

    [DllImport("user32")]
    protected static extern int SetWindowPos(int hwnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags);

    [DllImport("user32")]
    protected static extern bool DestroyWindow(int hwnd);

    int index;
    int deviceHandle;

    public TCamDevice(int index)
    {
        this.index = index;
    }

    private string _name;

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    private string _version;

    public string Version
    {
        get { return _version; }
        set { _version = value; }
    }

    public override string ToString()
    {
        return this.Name;
    }
    /// <summary>
    /// To Initialize the device
    /// </summary>
    /// <param name="windowHeight">Height of the Window</param>
    /// <param name="windowWidth">Width of the Window</param>
    /// <param name="handle">The Control Handle to attach the device</param>
    public void Init(int windowHeight, int windowWidth, int handle)
    {
        string deviceIndex = Convert.ToString(this.index);
        deviceHandle = capCreateCaptureWindowA(ref deviceIndex, WS_VISIBLE | WS_CHILD, 0, 0, windowWidth, windowHeight, handle, 0);

        if (SendMessage(deviceHandle, WM_CAP_DRIVER_CONNECT, this.index, 0) > 0)
        {
            SendMessage(deviceHandle, WM_CAP_SET_SCALE, -1, 0);
            SendMessage(deviceHandle, WM_CAP_SET_PREVIEWRATE, 0x42, 0);
            SendMessage(deviceHandle, WM_CAP_SET_PREVIEW, -1, 0);

            SetWindowPos(deviceHandle, 1, 0, 0, windowWidth, windowHeight, 6);
        }
    }

    /// <summary>
    /// Shows the webcam preview in the control
    /// </summary>
    /// <param name="windowsControl">Control to attach the webcam preview</param>
    public void ShowWindow(global::System.Windows.Forms.Control windowsControl)
    {
        Init(windowsControl.Height, windowsControl.Width, windowsControl.Handle.ToInt32());                        
    }

    /// <summary>
    /// Stop the webcam and destroy the handle
    /// </summary>
    public void Stop()
    {
        SendMessage(deviceHandle, WM_CAP_DRIVER_DISCONNECT, this.index, 0);

        DestroyWindow(deviceHandle);
    }
}

ShowWindow 将您的 PictureBox 作为参数。

【讨论】:

  • 我正在使用与您相同的方式,但我发现网络摄像头并不总是被调用。如果我重新启动系统,当我按下开始按钮时网络摄像头将调用,但如果我停止并再次按下开始然后视频不显示。 SendMessage(deviceHandle, WM_CAP_DRIVER_CONNECT, this.index, 0 的值为零,不显示视频。有人建议我每次都更改句柄/this.index 的值,但这也没有解决
  • 我也找不到如何保存这个以mp4格式获得的视频。请帮助
  • 然后我尝试调用 DeviceManager.GetAllDevices() 它抛出 "System.EntryPointNotFoundException: "Не удается найти точку входа "CapGetDriverDescriptionA" в DLL "avicap32.dll"。"" 我做错了什么?
  • 我的图片框变成了绿色! Windows 7 中没有其他内容。我的相机打开,但只显示绿色。 :-(
【解决方案2】:

我建议您使用 3rd 方库。这将是最好的解决方案,而不是发明自己的自行车。在这里,我使用了AForge.Net。虽然它在性能方面存在一些问题,但是当性能成为我的关键问题时,我自己调整了库。 AForge.Net 代码是开源的,您可以根据需要对其进行调整。

至于书籍,您绝对应该看看Jeffrey Richter's "CLR via C#"John Skeet's "C# in Depth"

【讨论】:

    【解决方案3】:

    您可以使用Microsoft Expression Encoder 4 SP2。这是一个很棒的库,您可以将其添加到您的项目中并获得实时预览、快照和视频录制。更多详细信息包含在 Massimo Conti 的示例项目中:How to use a web cam in C# with .NET Framework 4.0 and Microsoft Expression Encoder 4

    【讨论】:

      【解决方案4】:

      使用WebCam_Capture.dll 拍摄照片和视频。这是Link 这是LINK的源代码

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多