1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > C# 使用AForge调用笔记本摄像头拍照及录像

C# 使用AForge调用笔记本摄像头拍照及录像

时间:2021-08-22 06:58:41

相关推荐

C# 使用AForge调用笔记本摄像头拍照及录像

文章目录

1、添加引用2、AForge相关类库介绍3、WinForm界面实现4、属性5、窗口加载与关闭6、实例化7、 摄像头的连接读取与关闭8、拍照与保存9、录像10、计时器11、完整代码12、测试结果12、Demo下载13、踩坑经历及解决方案

1、添加引用

1、官网下载链接:/framework/downloads.html

2、通过管理Nuget程序包可直接添加以下引用,当然这里并没有全部用上,而只是用上了一部分

在添加完这些引用之后VS的工具箱当中会多出相关的一些控件,而实现调用摄像头就需要使用到这些控件

2、AForge相关类库介绍

AForge.dll 是框架的核心基础类库,为其他类库提供服务。

AForge.Controls.dll 包含的UI控件,主要用于页面显示。

AForge.Imaging.dll 主要是框架中用于图像处理的类库,主要负责图像的处理

AForge.Video.dll 主要是框架中对视频处理的类库。

AForge.Video.DirectShow.dll 主要是通过DirectShow接口访问视频资源的类库。

AForge.Video.FFMPEG.dll 是一个还未正式发布的类库,通过FFMPEG类库对视频进行读写。

3、WinForm界面实现

这里解释以下界面组成及控件使用

此界面分上下两部分

上中半部分由一个GroupBox包裹一个工具包VideoSourcePlayer控件命名为vsp_Panel组成

中间部分由一个Label,一个ComBox下拉框cb_CameraSelect,两个Button按钮btn_Connect、btn_Close组成

下半部分由分左右俩部分

下左部分由一个GroupBox包裹一个工具包PictureBox控件命名为pb_BoxPanel组成

下右部分由由一个GroupBox包裹5个Button按钮btn_StartVideo、btn_PauseVideo、btn_EndVideo、btn_Capture、btn_Save。以及两个label,其中录制时间:这个label命名无所谓后续用不到,而另外一个默认显示为00:00:00的label命名为lab_Time

4、属性

#region 属性/// <summary>/// 设备源/// 用来操作摄像头/// </summary>private AForge.Video.DirectShow.VideoCaptureDevice videoCapture;/// <summary>/// 摄像头设备集合/// </summary>private AForge.Video.DirectShow.FilterInfoCollection infoCollection;/// <summary>/// 图片/// </summary>private System.Drawing.Bitmap imgMap;/// <summary>/// 文件保存路径/// </summary>private readonly string filePath = $"D:\\VS主题\\图片\\";/// <summary>/// 文件名称/// </summary>private readonly string fileName = $"{DateTime.Now.ToString("yyyyMMddhhmmssffff")}";/// <summary>/// 用与把每一帧图像写入到视频文件/// </summary>private AForge.Video.FFMPEG.VideoFileWriter videoWriter;/// <summary>/// 是否开始录像/// </summary>private bool IsStartVideo = false;/// <summary>/// 写入次数/// </summary>private int tick_num = 0;/// <summary>/// 录制多少小时,只是为了定时间计算录制时间使用/// </summary>private int Hour = 0;/// <summary>/// 计时器/// </summary>private System.Timers.Timer timer_count;#endregion

5、窗口加载与关闭

#region 窗口加载与关闭/// <summary>/// 讲题加载事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void Form1_Load(object sender, EventArgs e){InitCamera();InitCameraSelect();this.btn_Capture.Enabled = false;this.btn_Save.Enabled = false;this.pb_BoxPanel.SizeMode = PictureBoxSizeMode.Zoom;//图片大小按比例适应控件,不加的话图片显示问题太大this.gb_CapturePanel.Visible = false;//默认不显示照片区域,拍照时在显示//秒表timer_count = new System.Timers.Timer(); //实例化Timer类,设置间隔时间为1000毫秒;timer_count.Elapsed += new System.Timers.ElapsedEventHandler(tick_count); //到达时间的时候执行事件;timer_count.AutoReset = true; //设置是执行一次(false)还是一直执行(true);timer_count.Interval = 1000;}/// <summary>/// 窗口关闭时/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void Form1_FormClosing(object sender, FormClosingEventArgs e){EndCamera();}#endregion

6、实例化

#region 实例化/// <summary>/// 实例化摄像头/// </summary>public void InitCamera(){try{//检测电脑上的摄像头设备infoCollection = new AForge.Video.DirectShow.FilterInfoCollection(AForge.Video.DirectShow.FilterCategory.VideoInputDevice);}catch (Exception ex){MessageBox.Show($"没有找到设备:{ex.Message}", "Error");}}//加载摄像头选择public void InitCameraSelect(){this.cb_CameraSelect.DropDownStyle = ComboBoxStyle.DropDownList;//根据读取到的摄像头加载选择项foreach (AForge.Video.DirectShow.FilterInfo item in infoCollection){this.cb_CameraSelect.Items.Add(item.Name);}//for (int i = 1; i <= infoCollection.Count; i++)//{// this.cb_CameraSelect.Items.Add("摄像头" + i);//}}#endregion

7、 摄像头的连接读取与关闭

#region 摄像头的连接读取与关闭/// <summary>/// 连接按钮/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btn_Connect_Click(object sender, EventArgs e){var CameraSelect = this.cb_CameraSelect.Text;var selectIndex = this.cb_CameraSelect.SelectedIndex;//已有连接的摄像头时先关闭if (videoCapture != null){EndCamera();}videoCapture = new AForge.Video.DirectShow.VideoCaptureDevice(infoCollection[selectIndex].MonikerString);//启动摄像头this.vsp_Panel.VideoSource = videoCapture;this.vsp_Panel.Start();this.btn_Capture.Enabled = true;this.btn_Save.Enabled = false;}/// <summary>/// 关闭按钮/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btn_Close_Click(object sender, EventArgs e){EndCamera();}/// <summary>/// 关闭摄像头/// </summary>public void EndCamera(){if (this.vsp_Panel.VideoSource != null){//也可以用 Stop() 方法关闭//指示灯停止且等待this.vsp_Panel.SignalToStop();//停止且等待this.vsp_Panel.WaitForStop();this.vsp_Panel.VideoSource = null;}}#endregion

8、拍照与保存

#region 拍照与保存/// <summary>/// 拍照/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btn_Capture_Click(object sender, EventArgs e){imgMap = this.vsp_Panel.GetCurrentVideoFrame();this.gb_CapturePanel.Visible = true;this.pb_BoxPanel.Image = imgMap;this.btn_Save.Enabled = true;}/// <summary>/// 保存事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btn_Save_Click(object sender, EventArgs e){var saveName = $"{filePath}{fileName}.jpg";imgMap.Save(saveName);this.btn_Save.Enabled = false;MessageBox.Show($"保存成功:{saveName}");}#endregion

9、录像

#region 录像/// <summary>/// 开始录像/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btn_StartVideo_Click(object sender, EventArgs e){string videoName = $"{filePath}{fileName}.MP4";IsStartVideo = true;//开始计时timer_count.Enabled = true;//配置录像参数(宽,高,帧率,比特率等参数)VideoCapabilities这个属性会返回摄像头支持哪些配置,从这里面选一个赋值接即可videoCapture.VideoResolution = videoCapture.VideoCapabilities[0];//设置回调,aforge会不断从这个回调推出图像数据videoCapture.NewFrame += Camera_NewFrame;videoWriter = new AForge.Video.FFMPEG.VideoFileWriter();//打开摄像头//videoCapture.Start();//打开录像文件(如果没有则创建,如果有也会清空),这里还有关于视频宽高、帧率、格式、比特率videoWriter.Open(videoName,videoCapture.VideoResolution.FrameSize.Width,videoCapture.VideoResolution.FrameSize.Height,videoCapture.VideoResolution.AverageFrameRate,AForge.Video.FFMPEG.VideoCodec.MPEG4,videoCapture.VideoResolution.BitCount);}//this.lab_Time//摄像头输出回调private void Camera_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs){imgMap = eventArgs.Frame;lock (imgMap){if (eventArgs != null && eventArgs.Frame != null){try{//写到文件videoWriter.WriteVideoFrame(eventArgs.Frame);}catch (Exception){}}}}/// <summary>/// 暂停录像/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btn_PauseVideo_Click(object sender, EventArgs e){var stopBtnName = this.btn_PauseVideo.Text;if (stopBtnName == "暂停录像"){this.btn_PauseVideo.Text = "恢复录像";//暂停计时timer_count.Enabled = false;IsStartVideo = false;}if (stopBtnName == "恢复录像"){this.btn_PauseVideo.Text = "暂停录像";//恢复计时timer_count.Enabled = true;IsStartVideo = true;}}/// <summary>/// 停止录像/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btn_EndVideo_Click(object sender, EventArgs e){IsStartVideo = false;timer_count.Enabled = false;videoWriter.Close();MessageBox.Show("停止录像");}#endregion

需要特别注意

videoWriter.Open(string fileName, int width, int height, int frameRate, VideoCodec codec, int bitRate);

width与height必须为偶数,否则报错Video file resolution must be a multiple of two.

10、计时器

#region 计时器响应函数/// <summary>/// 计时器/// </summary>/// <param name="source"></param>/// <param name="e"></param>public void tick_count(object source, System.Timers.ElapsedEventArgs e){tick_num++;int Temp = tick_num;int Second = Temp % 60;int Minute = Temp / 60;if (Minute % 60 == 0){Hour = Minute / 60;Minute = 0;}else{Minute = Minute - Hour * 60;}string HourStr = Hour < 10 ? $"0{Hour}" : Hour.ToString();string MinuteStr = Minute < 10 ? $"0{Minute}" : Minute.ToString();string SecondStr = Second < 10 ? $"0{Second}" : Second.ToString();String tick = $"{HourStr}:{MinuteStr}:{SecondStr}";this.Invoke((EventHandler)(delegate{this.lab_Time.Text = tick;}));}#endregion

11、完整代码

using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Controls;using System.Windows.Forms;namespace AForge拍照及录像{public partial class Form1 : Form{public Form1(){InitializeComponent();}#region 属性/// <summary>/// 设备源/// 用来操作摄像头/// </summary>private AForge.Video.DirectShow.VideoCaptureDevice videoCapture;/// <summary>/// 摄像头设备集合/// </summary>private AForge.Video.DirectShow.FilterInfoCollection infoCollection;/// <summary>/// 图片/// </summary>private System.Drawing.Bitmap imgMap;/// <summary>/// 文件保存路径/// </summary>private readonly string filePath = $"D:\\VS主题\\图片\\";/// <summary>/// 文件名称/// </summary>private readonly string fileName = $"{DateTime.Now.ToString("yyyyMMddhhmmssffff")}";/// <summary>/// 用与把每一帧图像写入到视频文件/// </summary>private AForge.Video.FFMPEG.VideoFileWriter videoWriter;/// <summary>/// 是否开始录像/// </summary>private bool IsStartVideo = false;/// <summary>/// 写入次数/// </summary>private int tick_num = 0;/// <summary>/// 录制多少小时,只是为了定时间计算录制时间使用/// </summary>private int Hour = 0;/// <summary>/// 计时器/// </summary>private System.Timers.Timer timer_count;#endregion#region 窗口加载与关闭/// <summary>/// 讲题加载事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void Form1_Load(object sender, EventArgs e){InitCamera();InitCameraSelect();this.btn_Capture.Enabled = false;this.btn_Save.Enabled = false;this.pb_BoxPanel.SizeMode = PictureBoxSizeMode.Zoom;//图片大小按比例适应控件,不加的话图片显示问题太大this.gb_CapturePanel.Visible = false;//默认不显示照片区域,拍照时在显示//秒表timer_count = new System.Timers.Timer(); //实例化Timer类,设置间隔时间为1000毫秒;timer_count.Elapsed += new System.Timers.ElapsedEventHandler(tick_count); //到达时间的时候执行事件;timer_count.AutoReset = true; //设置是执行一次(false)还是一直执行(true);timer_count.Interval = 1000;}/// <summary>/// 窗口关闭时/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void Form1_FormClosing(object sender, FormClosingEventArgs e){EndCamera();}#endregion#region 实例化/// <summary>/// 实例化摄像头/// </summary>public void InitCamera(){try{//检测电脑上的摄像头设备infoCollection = new AForge.Video.DirectShow.FilterInfoCollection(AForge.Video.DirectShow.FilterCategory.VideoInputDevice);}catch (Exception ex){MessageBox.Show($"没有找到设备:{ex.Message}", "Error");}}//加载摄像头选择public void InitCameraSelect(){this.cb_CameraSelect.DropDownStyle = ComboBoxStyle.DropDownList;//根据读取到的摄像头加载选择项foreach (AForge.Video.DirectShow.FilterInfo item in infoCollection){this.cb_CameraSelect.Items.Add(item.Name);}//for (int i = 1; i <= infoCollection.Count; i++)//{// this.cb_CameraSelect.Items.Add("摄像头" + i);//}}#endregion#region 摄像头的连接读取与关闭/// <summary>/// 连接按钮/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btn_Connect_Click(object sender, EventArgs e){var CameraSelect = this.cb_CameraSelect.Text;var selectIndex = this.cb_CameraSelect.SelectedIndex;//已有连接的摄像头时先关闭if (videoCapture != null){EndCamera();}videoCapture = new AForge.Video.DirectShow.VideoCaptureDevice(infoCollection[selectIndex].MonikerString);//启动摄像头this.vsp_Panel.VideoSource = videoCapture;this.vsp_Panel.Start();this.btn_Capture.Enabled = true;this.btn_Save.Enabled = false;}/// <summary>/// 关闭按钮/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btn_Close_Click(object sender, EventArgs e){EndCamera();}/// <summary>/// 关闭摄像头/// </summary>public void EndCamera(){if (this.vsp_Panel.VideoSource != null){//也可以用 Stop() 方法关闭//指示灯停止且等待this.vsp_Panel.SignalToStop();//停止且等待this.vsp_Panel.WaitForStop();this.vsp_Panel.VideoSource = null;}}#endregion#region 拍照与保存/// <summary>/// 拍照/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btn_Capture_Click(object sender, EventArgs e){imgMap = this.vsp_Panel.GetCurrentVideoFrame();this.gb_CapturePanel.Visible = true;this.pb_BoxPanel.Image = imgMap;this.btn_Save.Enabled = true;}/// <summary>/// 保存事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btn_Save_Click(object sender, EventArgs e){var saveName = $"{filePath}{fileName}.jpg";imgMap.Save(saveName);this.btn_Save.Enabled = false;MessageBox.Show($"保存成功:{saveName}");}#endregion#region 录像/// <summary>/// 开始录像/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btn_StartVideo_Click(object sender, EventArgs e){string videoName = $"{filePath}{fileName}.MP4";IsStartVideo = true;//开始计时timer_count.Enabled = true;//配置录像参数(宽,高,帧率,比特率等参数)VideoCapabilities这个属性会返回摄像头支持哪些配置,从这里面选一个赋值接即可videoCapture.VideoResolution = videoCapture.VideoCapabilities[0];//设置回调,aforge会不断从这个回调推出图像数据videoCapture.NewFrame += Camera_NewFrame;videoWriter = new AForge.Video.FFMPEG.VideoFileWriter();//打开摄像头//videoCapture.Start();//打开录像文件(如果没有则创建,如果有也会清空),这里还有关于视频宽高、帧率、格式、比特率videoWriter.Open(videoName,videoCapture.VideoResolution.FrameSize.Width,videoCapture.VideoResolution.FrameSize.Height,videoCapture.VideoResolution.AverageFrameRate,AForge.Video.FFMPEG.VideoCodec.MPEG4,videoCapture.VideoResolution.BitCount);}//this.lab_Time//摄像头输出回调private void Camera_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs){imgMap = eventArgs.Frame;lock (imgMap){if (eventArgs != null && eventArgs.Frame != null){try{//写到文件videoWriter.WriteVideoFrame(eventArgs.Frame);}catch (Exception){}}}}/// <summary>/// 暂停录像/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btn_PauseVideo_Click(object sender, EventArgs e){var stopBtnName = this.btn_PauseVideo.Text;if (stopBtnName == "暂停录像"){this.btn_PauseVideo.Text = "恢复录像";//暂停计时timer_count.Enabled = false;IsStartVideo = false;}if (stopBtnName == "恢复录像"){this.btn_PauseVideo.Text = "暂停录像";//恢复计时timer_count.Enabled = true;IsStartVideo = true;}}/// <summary>/// 停止录像/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btn_EndVideo_Click(object sender, EventArgs e){IsStartVideo = false;timer_count.Enabled = false;videoWriter.Close();MessageBox.Show("停止录像");}#endregion#region 计时器响应函数/// <summary>/// 计时器/// </summary>/// <param name="source"></param>/// <param name="e"></param>public void tick_count(object source, System.Timers.ElapsedEventArgs e){tick_num++;int Temp = tick_num;int Second = Temp % 60;int Minute = Temp / 60;if (Minute % 60 == 0){Hour = Minute / 60;Minute = 0;}else{Minute = Minute - Hour * 60;}string HourStr = Hour < 10 ? $"0{Hour}" : Hour.ToString();string MinuteStr = Minute < 10 ? $"0{Minute}" : Minute.ToString();string SecondStr = Second < 10 ? $"0{Second}" : Second.ToString();String tick = $"{HourStr}:{MinuteStr}:{SecondStr}";this.Invoke((EventHandler)(delegate{this.lab_Time.Text = tick;}));}#endregion}}

12、测试结果

拍照结果如下:

录像结果如下:

12、Demo下载

完整Demo下载: C# WinForm使用AForge拍照及录像

13、踩坑经历及解决方案

参考:细数AForge.Video.FFMPEG使用过程中踩的坑及解决方案

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。