我正在尝试编写一个应用程序,可以访问连接到PC的摄像头,录制视频并从视频中获取图像.我使用AForge.NET库访问摄像机:
http://www.aforgenet.com/framework/
我不知道如何命名为AForge.Video.NewFrameEventHandler的事件.在此代码中,事件将返回空值到位图而不是视频中的新帧,或者事件不被调用.我想要将帧从视频到每帧的图片框,以便像视频流一样,点击停止按钮后,我想让最后一张图像保持显示在图片框中.有人知道吗为什么我的代码不工作?
码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using AForge.Video.DirectShow; using System.Drawing; using AForge.Video; namespace CameraDevice { public class CameraImaging { // enumerate video devices public FilterInfoCollection videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice ); //camera public VideoCaptureDevice videoSource; //screen shot public Bitmap bitmap; public CameraImaging() { // create video source VideoCaptureDevice videoSource = new VideoCaptureDevice(videoDevices[0].MonikerString ); // set NewFrame event handler videoSource.NewFrame += new NewFrameEventHandler( video_NewFrame ); } public void StartVideo(VideoCaptureDevice videoSource) { // start the video source videoSource.Start(); // ... } public void StopVideo(VideoCaptureDevice videoSource) { // stop the video source videoSource.Stop(); // ... } private void video_NewFrame( object sender,NewFrameEventArgs eventArgs ) { // get new frame bitmap = eventArgs.Frame; // process the frame } } }
类似的代码在这里:http://www.aforgenet.com/framework/features/directshow_video.html[ ^]
在Windows窗体我运行这个视频在一个线程,这样做:
private void VideoRecording() { camImg.videoSource.Start(); while (!StopVideo) { pictureBox1.Image = camImg.bitmap; pictureBox1.Invalidate(); } camImg.videoSource.Stop(); }
解决方法
如果我记得正确,位图需要立即被复制,因为它在事件之后被覆盖.使用参考在这里是不好的.尝试像:
private void video_NewFrame( object sender,NewFrameEventArgs eventArgs ) { // copy the new frame bitmap = new Bitmap(eventArgs.Frame); // process the frame }
要么
private void video_NewFrame( object sender,NewFrameEventArgs eventArgs ) { // clone new frame bitmap = eventArgs.Frame.Clone(); // process the frame }
此外,您不应该为此使用额外的线程,AForge已经这样做了.
>呼叫开始(例如在加载事件中或按下按钮之后)
>处理框架事件
private void VideoStream_NewFrame(object sender,AForge.Video.NewFrameEventArgs eventArgs)
{
Bitmap newFrame = new Bitmap(eventArgs.Frame);
pictureBox1.Image = newFrame;
}
>呼叫停止(关闭事件或按钮)
如果遇到WinForm控件的问题,例如您需要知道这些控件是在另一个线程上创建的标签,您需要使用Invoke.例如:
label_ms.Invoke((MethodInvoker)(() => label_ms.Text = msTimeSpan.TotalMilliseconds.ToString()));
最好的办法是查看框架附带的AForge样本:
http://aforge.googlecode.com/svn/trunk/Samples/Video/Player/