zoukankan      html  css  js  c++  java
  • 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 = 0;
                this.Width = 0;
                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() == 0)
                    return;
    
                var webCamDevice = new WebcamDevice(this.VideoSourcePlayer1, mediaDeviceList.First().MonikerString);
                webCamDevice.Init();
            }
    
            private void InitBack()
            {
                if (mediaDeviceList.Count() <= 1)
                    return;
    
                var webCamDevice = new WebcamDevice(this.VideoSourcePlayer2, mediaDeviceList[1].MonikerString);
                webCamDevice.Init();
            }
        }

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

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

  • 相关阅读:
    Pyhton入门 笔记 第四天 Python的高级语法与用法
    Pyhton入门 笔记 第四天 正则表达式与JSON
    Pyhton入门 笔记 第三天 正则表达式与JSON
    Pyhton入门 笔记 第三天 面向对象 类
    Pyhton入门 练习 第三天 用循环输出小数点到某位
    Pyhton入门 笔记 第三天 函数
    Pyhton入门 笔记 第三天 包 模块 函数与变量作用域
    Pyhton入门 笔记 第二天 分支 循环 条件与枚举
    JS 获取地址栏参数
    文件的读取和写入
  • 原文地址:https://www.cnblogs.com/supperwu/p/10756203.html
Copyright © 2011-2022 走看看