本文简略地介绍一下如果使用AForge来实现前置/后置摄像头的预览功能。

要使用AForge,就需要添加AForge NuGet相关包的引用,这些包依赖的其他包会自动安装。

  • AForge.Controls
  • AForge.Video.DirectShow

接下来需要添加另外两个引用,主要是为了使用VideoSourcePlayer Windows Forms 控件。

  • System.Windows.Forms
  • WindowsFormsIntergration

UI界面比较简单,Xaml code 如下:

<Window x:Class="WebcamPreview.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:controls="clr-namespace:AForge.Controls;assembly=AForge.Controls"
mc:Ignorable="d"
Title="Webcam" Height="240" Width="640" MinHeight="240" MinWidth="640" ResizeMode="CanMinimize">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<WindowsFormsHost Background="Transparent">
<controls:VideoSourcePlayer x:Name="VideoSourcePlayer1" />
</WindowsFormsHost>
<WindowsFormsHost Background="Transparent" Grid.Column="1" >
<controls:VideoSourcePlayer x:Name="VideoSourcePlayer2" />
</WindowsFormsHost>
</Grid>
</Window>

定义一个描述video device的类。

    /// <summary>
/// Represents class that contains media information for video device source.
/// </summary>
public sealed class MediaInformation
{
/// <summary>
/// Gets or sets the display name of the video device source.
/// </summary>
public string DisplayName
{
get;
set;
} /// <summary>
/// Gets or sets the Moniker string of the video device source.
/// </summary>
public string MonikerString
{
get;
set;
}
}

实现一个WebcamDevice类,主要是用来初始化前置/后置摄像头的。

using AForge.Controls;
using AForge.Video.DirectShow;
using System;
using System.Collections.Generic;
using System.Linq; namespace WebcamPreview
{
public class WebcamDevice
{
// <summary>
/// Instance of video capture device.
/// </summary>
private VideoCaptureDevice videoCaptureDevice;
private VideoSourcePlayer videoPlayer;
private string deviceMoniker; public WebcamDevice(VideoSourcePlayer player, string deviceMoniker)
{
this.videoPlayer = player;
this.deviceMoniker = deviceMoniker;
} public void Init()
{
try
{
this.videoCaptureDevice = new VideoCaptureDevice(deviceMoniker);
this.videoPlayer.VideoSource = this.videoCaptureDevice;
this.videoPlayer.Start();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex);
}
} /// <summary>
/// Gets video device source collection current available.
/// </summary>
public static IReadOnlyList<MediaInformation> GetVideoDevices()
{
var filterVideoDeviceCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice);
return (from FilterInfo filterInfo
in filterVideoDeviceCollection
select new MediaInformation
{
DisplayName = filterInfo.Name,
MonikerString = filterInfo.MonikerString
}).ToList(); }
}
}

GetVideoDevices方法用来获取所有的摄像头。

Init方法,制定VideoSourcePlayer的VideoCaptureDevice是前置,还是后置摄像头。然后调用VideoSourcePlayer.Start方法就可以实现预览效果了。

最后就可以在MainWindow调用这个类了。

public partial class MainWindow : Window
{
private IReadOnlyList<MediaInformation> mediaDeviceList; public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;
this.Closed += MainWindow_Closed;
this.Deactivated += MainWindow_Deactivated;
this.Topmost = true;
} private void MainWindow_Closed(object sender, EventArgs e)
{
//防止视频关闭时画面延迟闪烁
this.Height = ;
this.Width = ;
if (!this.VideoSourcePlayer1.IsDisposed)
{
this.VideoSourcePlayer1.SignalToStop();
this.VideoSourcePlayer1.WaitForStop();
this.VideoSourcePlayer1.Stop();
this.VideoSourcePlayer1.VideoSource = null;
this.VideoSourcePlayer1.Dispose();
} if (!this.VideoSourcePlayer2.IsDisposed)
{
this.VideoSourcePlayer2.SignalToStop();
this.VideoSourcePlayer2.WaitForStop();
this.VideoSourcePlayer2.Stop();
this.VideoSourcePlayer2.VideoSource = null;
this.VideoSourcePlayer2.Dispose();
}
} private void MainWindow_Deactivated(object sender, EventArgs e)
{
this.Topmost = true;
} private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
this.mediaDeviceList = WebcamDevice.GetVideoDevices();
InitFront();
InitBack();
} private void InitFront()
{
if (mediaDeviceList.Count() == )
return; var webCamDevice = new WebcamDevice(this.VideoSourcePlayer1, mediaDeviceList.First().MonikerString);
webCamDevice.Init();
} private void InitBack()
{
if (mediaDeviceList.Count() <= )
return; var webCamDevice = new WebcamDevice(this.VideoSourcePlayer2, mediaDeviceList[].MonikerString);
webCamDevice.Init();
}
}

在Window的Closed事件,需要销毁VideoSourcePlayer对象。

另外指定Topmost=true,可以使这个窗口始终在最前面。

WPF使用AForge实现Webcam预览(一)的更多相关文章

  1. WPF使用AForge实现Webcam预览(二)

    本文主要介绍如何让摄像头预览界面的宽高比始终在16:9. 首先我们需要修改一下上一篇随笔实现的UI界面,让Grid变成一个3*3的九宫格,预览界面位于正中间.Xaml示例代码如下: <Windo ...

  2. 用WPF实现打印及打印预览

    原文:用WPF实现打印及打印预览 应该说,WPF极大地简化了我们的打印输出工作,想过去使用VC++做开发的时候,打印及预览可是一件极麻烦的事情,而现在我不会再使用C++来做Windows的桌面应用了- ...

  3. WPF的路由事件、冒泡事件、隧道事件(预览事件)

    本文摘要: 1:什么是路由事件: 2:中断事件路由: 3:自定义路由事件: 4:为什么需要自定义路由事件: 5:什么是冒泡事件和预览事件(隧道事件): 1:什么是路由事件 WPF中的事件为路由事件,所 ...

  4. [Aaronyang] 写给自己的WPF4.5 笔记15[AyArc诞生-WPF版本绚丽的环状图,Ay制作,AyWindow强势预览]

    原文:[Aaronyang] 写给自己的WPF4.5 笔记15[AyArc诞生-WPF版本绚丽的环状图,Ay制作,AyWindow强势预览]  我的文章一定要做到对读者负责,否则就是失败的文章  -- ...

  5. WPF中的事件及冒泡事件和隧道事件(预览事件)的区别

    WPF快速指导10:WPF中的事件及冒泡事件和隧道事件(预览事件)的区别   WPF快速指导10:WPF中的事件及冒泡事件和隧道事件(预览事件)的区别 本文摘要: 1:什么是路由事件: 2:中断事件路 ...

  6. WPF图片预览之移动、旋转、缩放

    原文:WPF图片预览之移动.旋转.缩放 RT,这个功能比较常见,但凡涉及到图片预览的都跑不了,在说自己的实现方式前,介绍一个好用的控件:Extended.Toolkit中的Zoombox,感兴趣的同学 ...

  7. WPF实现可视化控件打印及打印预览

    打印预览XAML代码: <controls:WindowEx x:Class="SunCreate.Vipf.Client.UI.MapPrintPreview" xmlns ...

  8. WPF 标签预览可以显示图片运行后不显示

    使用<Image HorizontalAlignment="Left" Height="100" Margin="106,111,0,0&quo ...

  9. winForm 打印预览

    自己很少写技术博客,虽然已经干程序员两年多了,winform开发,web开发都干过,不论项目大小对于.net的相关技术也是了解的,如mvc,wcf,wpf,silverlight,socekt通讯,n ...

随机推荐

  1. iOS 利用FZEasyFile本地保存 和 常规保存

    1.常规保存(较麻烦) NSFileManager *fileManager = [NSFileManager defaultManager]; //获取document路径,括号中属性为当前应用程序 ...

  2. DirectX11学习笔记

    一.假定每种颜色的原始点是不同,表面的这样的原始颜色将被指定为每种颜色用线性内插值传授,这个被称为高洛德着色(Gouraud Shading).也称为平滑阴影: 二.三维图元:Direct3D中.使用 ...

  3. 远程ssh执行命令时提示找不到命令

    最开始的时候碰到这种问题,是在hadoop003上配置了jdk1.8, 在hadoop002上执行ssh hadoop003 java -version提示没有命令,先ssh hadoop003然后执 ...

  4. 入坑cordova

    原文:入坑cordova 因项目需要入坑cordova,奔跑吧骚年,目前只是要求安卓平台,下面都是以安卓为例 最好的学习资料还是官网. https://cordova.apache.org/ http ...

  5. 【record】10.17..10.23

    .

  6. HDU 4313 Matrix 树形dp

    题意: 给定n个点的树,m个黑点 以下n-1行给出边和删除这条边的费用 以下m个黑点的点标[0,n-1] 删除一些边使得随意2个黑点都不连通. 问删除的最小花费. 思路: 树形dp 每一个点有2个状态 ...

  7. elasticsearch-jdbc

    jprante/elasticsearch-jdbc The Java Database Connection (JDBC) importer allows to fetch data from JD ...

  8. MyCat负载均衡 下篇

    MyCat负载均衡 下篇   之前在 一步一步在Windows中使用MyCat负载均衡 上篇 中已经讲了如何配置出MyCat.下面讲其相关的使用. 五.配置MyCat-eye 对于MyCat监控官网还 ...

  9. Method and Apparatus for Providing Highly-Scalable Network Storage for Well-Gridded Objects

    An apparatus comprising a plurality of storage nodes comprising a plurality of corresponding storage ...

  10. OpenCV dll 源码调试—附加到进程

    使用CMake可以生成OpenCV源码的解决方案,然后就可以对OpenCV函数进行修改,功能剪切等操作了,对这部分内容感兴趣的可以浏览一下上一篇文章:CMake生成OpenCV解决方案&&am ...