C# 利用Aforge调用本机摄像头完成拍照,录像

用C#做了一个简单的摄像头录像项目,记录一下。

实现功能

  1. 打开、关闭摄像头并显示相应画面
  2. 实现拍照功能
  3. 实现录像功能
  4. 实现保存图片、录像的功能

运行界面效果

在这里插入图片描述

winForm控件

在这里插入图片描述

首先安装NuGet程序包

右键解决方案
右键解决方案
点击红圈处
在这里插入图片描述
在搜索框中搜索“Aforge”,安装下面所有打勾的程序包(虽然没有全部用到)
在这里插入图片描述
引用和定义:

using System;
using System.Windows.Forms;
using System.IO;
using System.Windows.Media.Imaging;
using AForge.Video.DirectShow;
using Size = System.Drawing.Size;
using System.Windows;
using AForge.Video.FFMPEG;
namespace xxxx
{
 public partial class Form1 : Form
    {
        private delegate void MyDelegateUI();//多线程问题
        private VideoFileWriter videoWriter = null;     //写入到视频  
        private bool is_record_video = false;   //是否开始录像  
        private FilterInfoCollection videoDevices;
        private VideoCaptureDevice videoSource;

        System.Drawing.Bitmap bmp1 = null;
        System.Timers.Timer timer_count;
        int tick_num = 0;
        int hour = 0;
        int i = 1;           //统计摄像头个数
        int width = 640;    //录制视频的宽度
        int height = 480;   //录制视频的高度
        int fps = 20;        //正常速率,fps越大速率越快,相当于快进

        public Form1()
        {
            InitializeComponent();
        }
        ........
     }
}

窗体加载事件

       private void Form1_Load(object sender, EventArgs e)
        {
            //初始化按钮状态
            btnClose.Enabled = false;
            Photograph.Enabled = false;
            btnStarVideo.Enabled = false;
            btnPuaseVideo.Enabled = false;
            btnStopVideo.Enabled = false;

            try
            {
                // 枚举所有视频输入设备
                videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);

                if (videoDevices.Count == 0)
                    throw new ApplicationException();

                foreach (FilterInfo device in videoDevices)
                {
                    int i = 1;
                    tscbxCameras.Items.Add(device.Name);
                    textBoxC.AppendText("摄像头" + i + "初始化完毕..." + "\n");
                    textBoxC.ScrollToCaret();
                    i++;
                    Console.WriteLine(device.Name);
                }

                tscbxCameras.SelectedIndex = 0;

            }
            catch (ApplicationException)
            {
                tscbxCameras.Items.Add("没有本地设备");
                videoDevices = null;
            }

            //秒表
            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;
        }

计时器响应函数

        public void tick_count(object source, System.Timers.ElapsedEventArgs e)
        {
            tick_num++;
            int temp = tick_num;

            int sec = temp % 60;

            int min = temp / 60;
            if (min % 60 == 0)
            {
                hour = min / 60;
                min = 0;
            }
            else
            {
                min = min - hour * 60;
            }
            String tick = hour.ToString() + ":" + min.ToString() + ":" + sec.ToString();
            MyDelegateUI d = delegate
            {
                this.labelTime.Text = tick;
            };
            this.labelTime.Invoke(d);
        }

在“连接”(btnConnect)按钮中调用,连接摄像头的方法CameraConn()

        private void CameraConn()   
        {
            VideoCaptureDevice videoSource = new VideoCaptureDevice(videoDevices[tscbxCameras.SelectedIndex].MonikerString);
            videoSource.DesiredFrameSize = new Size(320, 240);
            videoSource.DesiredFrameRate = 1;

            videoSourcePlayer.VideoSource = videoSource;
            videoSourcePlayer.Start();
        }

     private void btnConnect_Click(object sender, EventArgs e)
        {
            CameraConn();
            //激活初始化按钮状态
            btnClose.Enabled = true;
            Photograph.Enabled = true;
            btnStarVideo.Enabled = true;
            btnPuaseVideo.Enabled = true;
            btnStopVideo.Enabled = true;
        }

关闭摄像头

  private void btnClose_Click(object sender, EventArgs e)
        {
            videoSourcePlayer.SignalToStop();
            videoSourcePlayer.WaitForStop();
        }

拍照,拍完直接保存
通过获取

   private string GetImagePath()
        {
            string personImgPath = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory)
                         + Path.DirectorySeparatorChar.ToString() + "PersonImg";
            if (!Directory.Exists(personImgPath))
            {
                Directory.CreateDirectory(personImgPath);
            }

            return personImgPath;
        }

 private void Photograph_Click(object sender, EventArgs e){
            try
            {
                if (videoSourcePlayer.IsRunning)
                {
                    //System.Windows.Media.Imaging
                    BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                                    videoSourcePlayer.GetCurrentVideoFrame().GetHbitmap(),
                                    IntPtr.Zero,
                                     Int32Rect.Empty,//System.Drawing.Imaging;
                                    BitmapSizeOptions.FromEmptyOptions());
                    PngBitmapEncoder pE = new PngBitmapEncoder();
                    pE.Frames.Add(BitmapFrame.Create(bitmapSource));
                    string picName = GetImagePath() + "\\" + "ceshiT" + ".jpg";
                    textBoxC.AppendText("保存路径:" + picName + "\n");
                    textBoxC.ScrollToCaret();

                    if (File.Exists(picName))
                    {
                        File.Delete(picName);
                    }
                    using (Stream stream = File.Create(picName))
                    {
                        pE.Save(stream);
                    }

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("摄像头异常:" + ex.Message);
            }
        }

退出按钮

private void btnExit_Click(object sender, EventArgs e)
        {
            if (this.videoWriter == null)
            {
                videoWriter = new VideoFileWriter();
            }
            if (this.videoWriter.IsOpen)
            {
                MessageBox.Show("视频流还没有写完,请点击结束录制。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }



            //拍照完成后关摄像头并刷新,同时关窗体
            if (videoSourcePlayer != null && videoSourcePlayer.IsRunning)
            {
                videoSourcePlayer.SignalToStop();
                videoSourcePlayer.WaitForStop();
            }

            this.Close();
        }

录像前先获取路径,因为开始录像后会要创建一个.avi的文件

   private String GetVideoPath()
        {
            String personImgPath = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory)
                         + Path.DirectorySeparatorChar.ToString() + "MyVideo";
            if (!Directory.Exists(personImgPath))
            {
                Directory.CreateDirectory(personImgPath);
            }

            return personImgPath;
        }

视频写入方法

 private void show_video(object sender, NewFrameEventArgs eventArgs)
        {
            try
            {
                Bitmap bitmap = AutomaticDestroyForm.automaticDestroyForm.videoSourcePlayer.GetCurrentVideoFrame();
                if (is_record_video)
                {
                    videoWriter.WriteVideoFrame(bitmap);
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show("视频写入问题:","错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

“开始录像”(btnStarVideo)按钮绑定事件

 private void btnStarVideo_Click(object sender, EventArgs e)
        {
            try
            {
                //创建一个视频文件
                String picName = GetVideoPath() + "\\" + DateTime.Now.ToString("yyyyMMdd HH-mm-ss") + ".avi";
                textBoxC.AppendText("Video保存地址:" + picName + "\n");
                textBoxC.ScrollToCaret();
                timer_count.Enabled = true;//是否执行System.Timers.Timer.Elapsed事件;
                textBoxC.AppendText("录制中...\n");
                is_record_video = true;
                videoWriter = new VideoFileWriter();
                if (videoSourcePlayer.IsRunning)
                {
                	//视频写入
                    videoSourcePlayer.NewFrame += new NewFrameEventHandler(show_video);
                    videoWriter.Open(picName, width, height, fps, VideoCodec.MPEG4);
                }
                else
                {
                    MessageBox.Show("没有视频源输入,无法录制视频。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("摄像头异常:" + ex.Message);
            }
        }

“暂停录像”(btnPuaseVideo)按钮绑定事件

 private void btnPuaseVideo_Click(object sender, EventArgs e)
        {

            if (this.btnPuaseVideo.Text.Trim() == "暂停录像")
            {
                is_record_video = false;
                this.btnPuaseVideo.Text = "恢复录像";
                timer_count.Enabled = false;    //暂停计时
                return;
            }
            if (this.btnPuaseVideo.Text.Trim() == "恢复录像")
            {
                is_record_video = true;
                this.btnPuaseVideo.Text = "暂停录像";
                timer_count.Enabled = true;     //恢复计时
            }
        }

“停止录像”(btnStopVideo)按钮绑定事件

     private void btnStopVideo_Click(object sender, EventArgs e)
        {
            this.is_record_video = false;
            this.videoWriter.Close();
            this.timer_count.Enabled = false;
            tick_num = 0;
            textBoxC.AppendText("录制停止!\n");
            textBoxC.ScrollToCaret();
        }
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值