WPF使用AForge实现Webcam预览(一)
本文简略地介绍一下如果使用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预览(一)的更多相关文章
- WPF使用AForge实现Webcam预览(二)
		本文主要介绍如何让摄像头预览界面的宽高比始终在16:9. 首先我们需要修改一下上一篇随笔实现的UI界面,让Grid变成一个3*3的九宫格,预览界面位于正中间.Xaml示例代码如下: <Windo ... 
- 用WPF实现打印及打印预览
		原文:用WPF实现打印及打印预览 应该说,WPF极大地简化了我们的打印输出工作,想过去使用VC++做开发的时候,打印及预览可是一件极麻烦的事情,而现在我不会再使用C++来做Windows的桌面应用了- ... 
- WPF的路由事件、冒泡事件、隧道事件(预览事件)
		本文摘要: 1:什么是路由事件: 2:中断事件路由: 3:自定义路由事件: 4:为什么需要自定义路由事件: 5:什么是冒泡事件和预览事件(隧道事件): 1:什么是路由事件 WPF中的事件为路由事件,所 ... 
- [Aaronyang] 写给自己的WPF4.5 笔记15[AyArc诞生-WPF版本绚丽的环状图,Ay制作,AyWindow强势预览]
		原文:[Aaronyang] 写给自己的WPF4.5 笔记15[AyArc诞生-WPF版本绚丽的环状图,Ay制作,AyWindow强势预览] 我的文章一定要做到对读者负责,否则就是失败的文章 -- ... 
- WPF中的事件及冒泡事件和隧道事件(预览事件)的区别
		WPF快速指导10:WPF中的事件及冒泡事件和隧道事件(预览事件)的区别 WPF快速指导10:WPF中的事件及冒泡事件和隧道事件(预览事件)的区别 本文摘要: 1:什么是路由事件: 2:中断事件路 ... 
- WPF图片预览之移动、旋转、缩放
		原文:WPF图片预览之移动.旋转.缩放 RT,这个功能比较常见,但凡涉及到图片预览的都跑不了,在说自己的实现方式前,介绍一个好用的控件:Extended.Toolkit中的Zoombox,感兴趣的同学 ... 
- WPF实现可视化控件打印及打印预览
		打印预览XAML代码: <controls:WindowEx x:Class="SunCreate.Vipf.Client.UI.MapPrintPreview" xmlns ... 
- WPF 标签预览可以显示图片运行后不显示
		使用<Image HorizontalAlignment="Left" Height="100" Margin="106,111,0,0&quo ... 
- winForm 打印预览
		自己很少写技术博客,虽然已经干程序员两年多了,winform开发,web开发都干过,不论项目大小对于.net的相关技术也是了解的,如mvc,wcf,wpf,silverlight,socekt通讯,n ... 
随机推荐
- 【Qt程序】基于Qt词典开发系列<十二>呼叫讲述
			我们知道,win7系统自带有讲述人,即能够机器读出当前内容,详细能够将电脑锁定.然后点击左下角的button就可以.之前在用Matlab写扫雷游戏的时候,也以前调用过讲述人来进行游戏的语音提示. 详细 ... 
- oracle表空间查询维护命令大全之中的一个(数据表空间)史上最全
			表空间是数据库的逻辑划分,一个表空间仅仅能属于一个数据库. 全部的数据库对象都存放在建立指定的表空间中.但主要存放的是表, 所以称作表空间.在oracle 数据库中至少存在一个表空间.即S ... 
- 垃圾回收GC:.Net自己主动内存管理 上(三)终结器
			垃圾回收GC:.Net自己主动内存管理 上(三)终结器 垃圾回收GC:.Net自己主动内存管理 上(一)内存分配 垃圾回收GC:.Net自己主动内存管理 上(二)内存算法 垃圾回收GC:.Net自己主 ... 
- Android Studio打包apk,aar,jar包
			转载请标明出处:一片枫叶的专栏 文本我们将讲解android studio打包apk,aar,jar包的相关知识.apk包就是android系统的安装包,这里没什么好说的,aar包是android中独 ... 
- 【34.40%】【codeforces 711D】Directed Roads
			time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ... 
- apply plugin: 'idea'  --- gradle idea
			如果你的项目使用了Gradle作为构建工具,那么你一定要使用Gradle来自动生成IDE的项目文件,无需再手动的将源代码导入到你的IDE中去了. 如果你使用的是eclipse,可以在build.gra ... 
- Step-By-Step Installation of RAC with RAW Datafiles on Windows  2000
			 Step-By-Step Installation of RAC with RAW Datafiles on Windows 2000 Purpose This document will pr ... 
- wpf控件设计时支持(1)
			原文:wpf控件设计时支持(1) 这部分内容几乎是大家忽略的内容,我想还是来介绍一下. 本篇源码下载 1.属性元数据 在vs IDE中,在asp.net,winfrom等开发环境下,右侧的Proper ... 
- string操作
			常用的功能测试: #! -*- coding:utf-8 -*- import string s = 'Yes! This is a string' print '原字符串:' + s print ' ... 
- WPF中使用Hashtable剔除重复字符串(比如电话号码)
			原文:WPF中使用Hashtable剔除重复字符串(比如电话号码) 本文中的输入框中的字符串是逗号隔开的,你可以换成其他特别的字符串.本篇中的亮点:1. 里面有一个玻璃样式按钮,用XAML制作2. W ... 
