不废话,直接上干货。
1,首先NuGet里添加AForge,共需要7个如下图。其中第五个“AForge.Video.FFMPEG"NuGet里是没有的稍后奉上。
2,工具栏里新建新建选项卡,并将AForge.Controls导入,成功后会增加几个控件(此处不会自行百度)。
3,添加”AF"控件下的“PictureBox"控件到窗体,用来显示摄像头采集的图像。添加一个ComBobox控件用来显示摄像头列表。添加4个按钮功能如图。按钮名称自己比对。
代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using AForge;
using AForge.Imaging;
using AForge.Imaging.Filters;
using AForge.Video;
using AForge.Video.DirectShow;
using AForge.Video.FFMPEG;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using AForge.Controls;
namespace USB摄像头拍照录像
{
public partial class Form1 : Form
{
#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;
/// <summary>
/// 文件名称
/// </summary>
private readonly string fileName;
/// <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>
public void EndCamera()
{
if (this.vsp_box.VideoSource != null)
{
//也可以用 Stop() 方法关闭
//指示灯停止且等待
this.vsp_box.SignalToStop();
//停止且等待
this.vsp_box.WaitForStop();
this.vsp_box.VideoSource = null;
}
}
#endregion
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
InitCamera();
InitCameraSelect();
this.btn_photo.Enabled = 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;
if (DateTime.Now.Month > 3) { return; }
}
#region 视频控制1
private void uiSymbolButton2_Click_1(object sender, EventArgs e)
{
try
{
if (cb_CameraSelect.SelectedIndex == -1) { MessageBox.Show("先选择相机"); return; }
if (this.btn_photo.Enabled == false)
{
EndCamera();
btn_view.Text = "停止";
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_box.VideoSource = videoCapture;
this.vsp_box.Start();
this.btn_photo.Enabled = true;
btn_video.Enabled = true;
// this.btn_Save.Enabled = false;
}
else
{
btn_video.Enabled = false;
btn_view.Text = "预览";
this.btn_photo.Enabled = false;
// btn_Capture.Enabled = true;
EndCamera();
}
}
catch (Exception ex) { MessageBox.Show(ex.Message); }
}
private void uiSymbolButton1_Click(object sender, EventArgs e)
{
InitCamera();
InitCameraSelect();
this.btn_photo.Enabled = 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;
}
private void btn_photo_Click(object sender, EventArgs e)
{
try
{
imgMap = this.vsp_box.GetCurrentVideoFrame();
// this.groupBox2.Visible = true;
SaveFileDialog sfd = new SaveFileDialog();
sfd.InitialDirectory = ".\\";
sfd.Filter = "jpg(*.jpg)|*.jpg";
if (sfd.ShowDialog() == DialogResult.OK)
{
pathPhoto = sfd.FileName;
// btn_StartVideo.Text = "Stop";
}
FiltersSequence filter = new FiltersSequence();
filter.Add(new Grayscale(0.2125, 0.7154, 0.0721));
filter.Add(new Threshold(128));
Bitmap image = new Bitmap(imgMap);
var saveName = pathPhoto;
image.Save(saveName);
}
catch (Exception ex) { MessageBox.Show(ex.Message); }
}
string pathVideo;
string pathPhoto;
private void btn_video_Click(object sender, EventArgs e)
{
try
{
if (btn_video.Text == "停止")
{
IsStartVideo = false;
timer_count.Enabled = false;
videoWriter.Close();
btn_video.Text = "录像";
btn_photo.Enabled = true;
return;
}
btn_photo.Enabled = false;
SaveFileDialog sfd = new SaveFileDialog();
sfd.InitialDirectory = ".\\";
sfd.Filter = "avi(*.avi)|*.avi";
if (sfd.ShowDialog() == DialogResult.OK)
{
pathVideo = sfd.FileName;
btn_video.Text = "Stop";
}
else
{
btn_photo.Enabled = true;
return;
}
string videoName = pathVideo;
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
);
}
catch (Exception ex) { MessageBox.Show(ex.Message); }
// finally { btn_video.Enabled = true; }
}
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)
{
}
}
}
}
#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()
{
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
private void btn_view_Click(object sender, EventArgs e)
{
try
{
if (cb_CameraSelect.SelectedIndex == -1) { MessageBox.Show("先选择相机"); return; }
if (this.btn_photo.Enabled == false)
{
EndCamera();
btn_view.Text = "停止";
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_box.VideoSource = videoCapture;
this.vsp_box.Start();
this.btn_photo.Enabled = true;
btn_video.Enabled = true;
// this.btn_Save.Enabled = false;
}
else
{
btn_video.Enabled = false;
btn_view.Text = "Preview";
this.btn_photo.Enabled = false;
// btn_Capture.Enabled = true;
EndCamera();
}
}
catch (Exception ex) { MessageBox.Show(ex.Message); }
}
private void btn_refr_Click(object sender, EventArgs e)
{
InitCamera();
InitCameraSelect();
this.btn_photo.Enabled = false;
// this.btn_Save.Enabled = false;
// this.pb_BoxPanel.SizeMode = PictureBoxSizeMode.Zoom;//图片大小按比例适应控件,不加的话图片显示问题太大
//this.groupBox2.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;
}
}
#endregion
}
完全照搬后如果不出意外肯定会出现以外。
出现这个情况一点都不意外,但是解决他光在网上搜资料就用了一天的时间。网上的办法很多,但我是用这个方法解决的。
首先将运行平台改为X86
然后在输出目录(DEBUG)下加入以下DLL即可。