• 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;
            }
        }
    }
  • 相关阅读:
    Mysql 优化 or
    为什么 Mysql 推荐使用整形自增的主键而不使用 UUID
    Mysql 索引上做计算为什么会导致索引失效
    SQL 提示
    索引语法
    Mysql 优化 limit 1
    Mysql 优化 like
    SpringCloud Feign 报错 Request method 'POST' not supported 的解决办法
    前缀索引
    Explain 关键字
  • 原文地址:https://www.cnblogs.com/lnsane/p/13944861.html
Copyright © 2020-2023  润新知