最近由于某种原因呢,需要做一下拍照的功能,本来我纠结到底用AForge类库还是用WPFMediaKit.dll ,不过后来看网上说WPFMediaKit.dll 是截图而AForge是直接通过摄像头拍照,于是乎,我就选择了AForge类库。
首先留下发帖时我所用的AForge 链接: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;}} }