本文简略地介绍一下如果使用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. Erlang/OTP 中文手册

    http://erldoc.com/ Open Telecom Platform application array asn1rt base64 binary calendar code dbg di ...

  2. hadoop实现购物商城推荐系统

    1,商城:是单商家,多买家的商城系统.数据库是mysql,语言java. 2,sqoop1.9.33:在mysql和hadoop中交换数据. 3,hadoop2.2.0:这里用于练习的是伪分布模式. ...

  3. python request post

    import requests import json class BaiduTranslateSpider: def __init__(self, kw): self.url = "htt ...

  4. android tips—开机引导启动wifi设置

    在开机引导(Setupwizard,Guide)中都有关于wifi设置项,我得做法例如以下: Intent intent = new Intent(); intent.setClassName(&qu ...

  5. SQLite做为本地缓存的应用需要注意的地方

    原文:SQLite做为本地缓存的应用需要注意的地方 今天看到了园友陆敏计的一篇文章<<C#数据本地存储方案之SQLite>>, 写到了SQLite的诸多优点,尤其适应于本地数据 ...

  6. Twitter "like" 动画实战

    http://zhuanlan.zhihu.com/FrontendMagazine/20486738

  7. IIS相关优化

    1.修改IIS最大工作进程数 a. 请考虑以下几点: 1.每一个工作进程都会消耗系统资源和CPU占用率:太多的工作进程会导致系统资源和CPU利用率的急剧消耗: 2.每一个工作进程都具有自己的状态数据, ...

  8. 解决:eth0安装插卡无法自己主动,网卡的配置信息不network-scripts于

    问题方案:eth0安装插卡无法自己主动,网卡的配置信息不network-scripts于 解决: 1>vi /etc/rc.d/rc.loacl 最后加 ifup eth0 2>reboo ...

  9. ssh探头安全

    1.  ssh 合约                 SSH 为建立在应用层和传输层基础上的安全协议. SSH 是眼下较可靠,专为远程登录会话和其它网络服务提供安全性的协议.利用 SSH 协议能够有效 ...

  10. Android新闻案例clientserver达到,完全自己的新闻节目平台

    一.建设新闻资料库 例如,下面的脚本代码:(正在使用mysql5.0 数据库) SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_z ...