WPF中通过AForge实现USB摄像头拍照

转载:https://www.cnblogs.com/lingLuoChengMi/p/8466559.html

最近由于某种原因呢,需要做一下拍照的功能,本来我纠结到底用AForge类库还是用WPFMediaKit.dll ,不过后来看网上说WPFMediaKit.dll 是截图而AForge是直接通过摄像头拍照,于是乎,我就选择了AForge类库。

首先留下发帖时我所用的AForge(NuGet包管理器可下载)    链接:https://pan.baidu.com/s/1htmOjPi 密码:tovd

第一步

  将AForge中的DLL添加进引用,然后添加引用System.Drawing,System.Windows.Forms,WindowsFormsIntegration

第二步

  加上

   xmlns:wfi ="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
        xmlns:aforge ="clr-namespace:AForge.Controls;assembly=AForge.Controls"

  还有

  <wfi:WindowsFormsHost Grid.Row="0" HorizontalAlignment="Left" Width="517" Height="320" VerticalAlignment="Top">
            <aforge:VideoSourcePlayer x:Name="player" Height="480" Width="640"/>
        </wfi:WindowsFormsHost>

  下面贴详细代码

MainWindow.xaml

<Window x:Class="FaceOne.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:FaceOne"
        xmlns:wfi ="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
        xmlns:aforge ="clr-namespace:AForge.Controls;assembly=AForge.Controls"
        mc:Ignorable="d"
        Title="MainWindow" Height="600" Width="800" Loaded="Window_Loaded">
    <Grid>
        <wfi:WindowsFormsHost Grid.Row="0" HorizontalAlignment="Left" Width="517" Height="320" VerticalAlignment="Top">
            <aforge:VideoSourcePlayer x:Name="player" Height="480" Width="640"/>
        </wfi:WindowsFormsHost>
        <Button x:Name="connectBtn" Content="连接" HorizontalAlignment="Left" Margin="53,439,0,0" VerticalAlignment="Top" Width="75" Click="connectBtn_Click"/>
        <Button x:Name="captureBtn" Content="拍照" HorizontalAlignment="Left" Margin="180,439,0,0" VerticalAlignment="Top" Width="75" Click="captureBtn_Click"/>
        <Button x:Name="closeBtn" Content="断开" HorizontalAlignment="Left" Margin="312,439,0,0" VerticalAlignment="Top" Width="75" Click="closeBtn_Click"/>
        <Image x:Name="imageCapture" HorizontalAlignment="Left" Height="210" Margin="522,66,0,0" VerticalAlignment="Top" Width="239"/>

    </Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace FaceOne
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        MyCapture myCapture = MyCapture.Instance();
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //myCapture.sourcePlayer = player;//配置好XAML后再加上这句,即可看到摄像头的视图

            myCapture.getCamera();//获取摄像头
            myCapture.saveOk += ImageSaveOk;//保存照片后触发
        }


        //连接
        private void connectBtn_Click(object sender, RoutedEventArgs e)
        {
            myCapture.CameraConn();
        }
        //拍照
        private void captureBtn_Click(object sender, RoutedEventArgs e)
        {
            myCapture.CaputreImage();
        }
        //断开
        private void closeBtn_Click(object sender, RoutedEventArgs e)
        {
            myCapture.CloseDevice();
        }
        //保存照片后触发(想看预览就用,不想看就不需要了)
        private void ImageSaveOk(string str)
        {
            /*//老套的赋值方式,不会释放内存
            BitmapImage bit = new BitmapImage();
            bit.BeginInit();
            bit.UriSource = new Uri(AppDomain.CurrentDomain.BaseDirectory+str);
            bit.EndInit();
            imageCapture.Source = bit;*/


            BitmapImage bmi = myCapture.InitImage(str);
            imageCapture.Source = bmi;
        }
    }
}

MyCapture.cs

using AForge.Controls;
using AForge.Video.DirectShow;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;

namespace FaceOne
{
    class MyCapture
    {
        public delegate void SaveOk(string str);
        public SaveOk saveOk;

        private static MyCapture instance;
        public static MyCapture Instance()
        {
            if (instance == null)
            {
                instance = new MyCapture();
            }
            return instance;
        }

        //private static FilterInfoCollection _cameraDevices;
        private FilterInfoCollection videoDevices;
        //private static VideoCaptureDevice div = null;
        VideoCaptureDevice videoSource;
        public VideoSourcePlayer sourcePlayer = new VideoSourcePlayer();

        public void getCamera()
        {
            // 获取电脑已经安装的视频设备
            videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            if (videoDevices != null && videoDevices.Count > 0)
            {
                foreach (FilterInfo device in videoDevices)
                {
                    Console.WriteLine(device.Name);
                }
                //CameraConn();
            }
        }
        //连接并且打开摄像头
        public void CameraConn()
        {
            if (videoDevices.Count <= 0)
            {
                Console.WriteLine("请插入视频设备");
                return;
            }

            videoSource= new VideoCaptureDevice(videoDevices[0].MonikerString);//连接到第一个设备,可灵活改动
            //videoSource.DesiredFrameSize = new System.Drawing.Size(240, 320);
            //videoSource.DesiredFrameRate = 1;

            sourcePlayer.VideoSource = videoSource;

            videoSource.Start();
            sourcePlayer.Start();
            
        }
        //截取一帧图像并保存
        public void CaputreImage(string filePath=null,string fileName=null)
        {
            if (sourcePlayer.VideoSource == null)
            {
                return;
            }
            //判断是否有这个目录,如果没有则新创建这个目录
            /*if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }*/
            try
            {
                Image bitmap = sourcePlayer.GetCurrentVideoFrame();
                /*if (fileName == null)
                {
                    fileName = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss");
                }*/
                //string str = @"" + fileName + ".jpg";
                string str = "asd.jpg";//使用InitImage可以重复读写一张图,不用的话,就只能一直保存新的图片了
                bitmap.Save(str,ImageFormat.Jpeg); //想看预览就用,不想看就不需要了

                bitmap.Dispose();

                saveOk(str);
            }
            catch(Exception e)
            {
                Console.WriteLine(e.Message.ToString());
            }
        }
        //关闭摄像头设备
        public void CloseDevice()
        {
            if (videoSource != null && videoSource.IsRunning)
            {
                sourcePlayer.Stop();
                videoSource.SignalToStop();
                videoSource = null;
                videoDevices = null;
            }
        }

        //解决不同进程读取同一张图片的问题,使用流来读图片
        public BitmapImage InitImage(string filePath)
        {
            BitmapImage bitmapImage;
            using (BinaryReader reader = new BinaryReader(File.Open(filePath, FileMode.Open)))
            {
                FileInfo fi = new FileInfo(filePath);
                byte[] bytes = reader.ReadBytes((int)fi.Length);
                reader.Close();

                //image = new Image();
                bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.StreamSource = new MemoryStream(bytes);
                bitmapImage.EndInit();
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                //image.Source = bitmapImage;
                reader.Dispose();
            }
            return bitmapImage;
        }
    }
}
posted @ 2020-11-08 16:53  lnsane-G  阅读(588)  评论(0编辑  收藏  举报