65.9K
CodeProject 正在变化。 阅读更多。
Home

带计划功能的摄像头应用程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.25/5 (7投票s)

2011年12月5日

CPOL

2分钟阅读

viewsIcon

40551

downloadIcon

6988

一个具有计划功能的摄像头应用程序,用于捕捉视频。

引言

这个应用程序使用摄像头捕捉视频到文件(.avi)。它还具有计划录制时间的功能,可以自动开始视频捕捉。我们可以使用任何摄像头,并设置各种属性来配合摄像头使用,例如视频大小、源和摄像头本身的设置。

背景

这段代码的基础是使用 avicap32 DLL。使用这个 DLL,你可以连接到摄像头并设置其设置。我们使用 SendMessage 向摄像头发送消息,例如连接和捕捉视频。关于这个主题已经有一些现有的文章,但我会尝试把它写得非常简单。

Using the Code

我们需要做的第一件事是设置我们的捕捉控件。我使用一个简单的 PictureBox 控件来托管摄像头的输出。

这只需要一行代码即可完成

mCapHwnd = capCreateCaptureWindowA("WebCap", WS_VISIBLE | WS_CHILD, 0, 0,
   this.pictureBox1.Width, this.pictureBox1.Height, 
   this.pictureBox1.Handle.ToInt32(), 0);

接下来我们需要连接到我们的摄像头

SendMessage(mCapHwnd, WM_CAP_CONNECT, 0, 0);

接下来我们需要几行代码来设置摄像头设置

//Set the frame rate for the WebCam
SendMessage(mCapHwnd, WM_CAP_SET_PREVIEWRATE, 66, 0);
//Set the preview flag to true
SendMessage(mCapHwnd, WM_CAP_SET_PREVIEW, 1, 0);
//Set thisif you want to control the video compression for the output video
SendMessage(mCapHwnd, WM_CAP_DLG_VIDEOCOMPRESSION, 0, 0);

为了捕捉视频,你必须设置各种视频属性,例如是否要捕捉音频等。我们需要使用 CAPTUREPARMS 结构来实现这一点。你可以在源代码下载中找到它的声明。下一行使用 CAPTUREPARMS 结构来设置我们想要的摄像头设置

SendMessage2(mCapHwnd, WM_CAP_SET_SEQUENCE_SETUP,
 new IntPtr(Marshal.SizeOf(CaptureParams)),ref CaptureParams);

CAPTUREPARMS 结构中的一个重要参数是 fYield。如果希望在与表单不同的线程中捕捉视频,请将其设置为 true (1)。

接下来,我们想将视频捕捉到 PictureBox 控件中。我们通过调用此消息来做到这一点

SendMessage(mCapHwnd, WM_CAP_GRAB_FRAME_NOSTOP, 0, 0);

我们需要在计时器滴答事件中调用此行,以便获得连续的视频。我使用了 System.Threading.Timer 来实现这一点。

private void DoIt()
{
    System.Threading.Timer t = null;
    t = new System.Threading.Timer(delegate(object state)
    {
        t.Dispose();
        CaptureImage();
        DoIt();
    }, null, 66, -1);
}

接下来我们需要将视频捕捉到文件(默认文件是使用 avicap32.dll.avi 文件)

string file = DateTime.Now.ToShortDateString().Replace('/','_') +
 "_" + DateTime.Now.ToLongTimeString().Replace(':','_') + ".avi";
SendMessageA(mCapHwnd, WM_CAP_FILE_SET_CAPTURE_FILEA, 0, dir +
 Path.DirectorySeparatorChar + file);
SendMessage(mCapHwnd, WM_CAP_SEQUENCE, 0, 0);

接下来的两个方法用于配置摄像头源和格式。只有在你不想使用摄像头的默认设置时才使用它们。

private void btnConfig_Click(object sender, EventArgs e)
{
    SendMessage(mCapHwnd, WM_CAP_DLG_VIDEOSOURCE, 0, 0);
}
private void btnFormat_Click(object sender, EventArgs e)
{
    SendMessage(mCapHwnd, WM_CAP_DLG_VIDEOFORMAT, 0, 0);
}

代码的计划部分非常简单。我使用 app.config 文件来存储我想要开始捕捉的时间,并使用 Timer 控件来检查是否是开始捕捉的时间。你可以在源代码下载中查看此内容。

好的,剩下的唯一事情就是在完成工作后断开与摄像头的连接

SendMessage(mCapHwnd, WM_CAP_DISCONNECT, 0, 0);

就这样了。希望我成功地保持了它的简单性。

关注点

这是我第一次使用摄像头编写应用程序。你也可以使用 DirectX 来做同样的事情,但我发现这种方法既快速又简单。

© . All rights reserved.