WPF实现调用本机摄像头的示例代码

 更新时间:2022年08月03日 17:11:23   作者:驚鏵  
这篇文章主要介绍了如何利用WPF实现调用本机摄像头,文中的示例代码讲解详细,对我们学习或工作有一定帮助,需要的可以参考一下

此项目使用了OpenCVSharp加载本地摄像头,多个摄像头支持切换展示,也可以展示rtsp地址。

使用NuGet如下:

代码如下

一、创建MainWindow.xaml代码如下。

 <ws:Window x:Class="OpenCVSharpExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ws="https://github.com/WPFDevelopersOrg.WPFDevelopers.Minimal"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:OpenCVSharpExample"
        Icon="OpenCV_Logo.png"
        mc:Ignorable="d" WindowStartupLocation="CenterScreen"
        Title="OpenCVSharpExample https://github.com/WPFDevelopersOrg" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition />
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ComboBox Name="ComboBoxCamera" ItemsSource="{Binding CameraArray,RelativeSource={RelativeSource AncestorType=local:MainWindow}}" 
                  Width="200" SelectedIndex="{Binding CameraIndex,RelativeSource={RelativeSource AncestorType=local:MainWindow}}"
                  SelectionChanged="ComboBoxCamera_SelectionChanged"/>
        <Image Grid.Row="1" Name="imgViewport" Margin="0,4"/>
        <StackPanel Orientation="Horizontal"
                    HorizontalAlignment="Center"
                    Grid.Row="2">
            <!--<Button Name="btRecord" Click="btRecord_Click" Content="Record" Style="{StaticResource PrimaryButton}" Width="100" Height="50" Margin="16"/>-->
            <Button Name="btStop" Click="btStop_Click" Content="Stop"  Width="100" Height="50" Margin="16"/>
        </StackPanel>
    </Grid>
</ws:Window>

二、MainWindow.xaml.cs代码如下。

using OpenCvSharp;
using OpenCvSharp.Extensions;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Management;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.Windows.Threading;

namespace OpenCVSharpExample
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow
    {
        private VideoCapture capCamera;
        private Mat matImage = new Mat();
        private Thread cameraThread;

        public List<string> CameraArray
        {
            get { return (List<string>)GetValue(CameraArrayProperty); }
            set { SetValue(CameraArrayProperty, value); }
        }

        public static readonly DependencyProperty CameraArrayProperty =
            DependencyProperty.Register("CameraArray", typeof(List<string>), typeof(MainWindow), new PropertyMetadata(null));



        public int CameraIndex
        {
            get { return (int)GetValue(CameraIndexProperty); }
            set { SetValue(CameraIndexProperty, value); }
        }

        public static readonly DependencyProperty CameraIndexProperty =
            DependencyProperty.Register("CameraIndex", typeof(int), typeof(MainWindow), new PropertyMetadata(0));



        

        public MainWindow()
        {
            InitializeComponent();
            Width = SystemParameters.WorkArea.Width / 1.5;
            Height = SystemParameters.WorkArea.Height / 1.5;
            this.Loaded += MainWindow_Loaded;

        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            InitializeCamera();
        }
        private void ComboBoxCamera_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (CameraArray.Count - 1 < CameraIndex)
                return;

            if (capCamera != null && cameraThread != null)
            {
                cameraThread.Abort();
                StopDispose();
            }

            capCamera = new VideoCapture(CameraIndex);
            capCamera.Fps = 30;
            CreateCamera();
            
        }

        private void InitializeCamera()
        {
            CameraArray = GetAllConnectedCameras();
        }
        List<string> GetAllConnectedCameras()
        {
            var cameraNames = new List<string>();
            using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE (PNPClass = 'Image' OR PNPClass = 'Camera')"))
            {
                foreach (var device in searcher.Get())
                {
                    cameraNames.Add(device["Caption"].ToString());
                }
            }

            return cameraNames;
        }

        void CreateCamera()
        {
            cameraThread = new Thread(PlayCamera);
            cameraThread.Start();
        }

        private void PlayCamera()
        {
            while (capCamera != null && !capCamera.IsDisposed)
            {
                capCamera.Read(matImage);
                if (matImage.Empty()) break;
                Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
                {
                    var converted = Convert(BitmapConverter.ToBitmap(matImage));
                    imgViewport.Source = converted;
                }));
            }
        }
       
        private void btStop_Click(object sender, RoutedEventArgs e)
        {
            StopDispose();
            btStop.IsEnabled = false;
        }

        void StopDispose()
        {
            if (capCamera != null && capCamera.IsOpened())
            {
                capCamera.Dispose();
                capCamera = null;
            }
        }

        void CreateRecord()
        {
            cameraThread = new Thread(PlayCamera);
            cameraThread.Start();
        }

        BitmapImage Convert(Bitmap src)
        {
            System.Drawing.Image img = src;
            var now = DateTime.Now;
            var g = Graphics.FromImage(img);
            var brush = new SolidBrush(System.Drawing.Color.Red);
            g.DrawString($"北京时间:{ now.ToString("yyyy年MM月dd日 HH:mm:ss")}", new System.Drawing.Font("Arial", 18), brush, new PointF(5, 5));
            brush.Dispose();
            g.Dispose();
            MemoryStream ms = new MemoryStream();
            img.Save(ms, ImageFormat.Bmp);
            ms.Seek(0, SeekOrigin.Begin);
            BitmapImage image = new BitmapImage();
            image.BeginInit();
            image.StreamSource = ms;
            image.EndInit();
            image.Freeze();
            return image;
        }

        protected override void OnClosed(EventArgs e)
        {
            StopDispose();
        }


    }
}

效果预览

源码地址如下

Github:https://github.com/WPFDevelopersOrg

https://github.com/WPFDevelopersOrg/OpenCVSharpExample

Gitee:https://gitee.com/WPFDevelopersOrg

到此这篇关于WPF实现调用本机摄像头的示例代码的文章就介绍到这了,更多相关WPF调用摄像头内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#把数字转换成大写金额的代码实例

    C#把数字转换成大写金额的代码实例

    这篇文章主要介绍了C#把数字转换成大写金额的代码实例,例如把200转换成“贰佰元”,需要的朋友可以参考下
    2014-05-05
  • C# 实现连连看功能(推荐)

    C# 实现连连看功能(推荐)

    本文是利用C#实现连连看的小例子,使用线程thread实现后台运行时间控制,实现代码简单易懂,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-07-07
  • C# Socket编程实现简单的局域网聊天器的示例代码

    C# Socket编程实现简单的局域网聊天器的示例代码

    这篇文章主要介绍了C# Socket编程实现简单的局域网聊天器,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • C#写差异文件备份工具的示例

    C#写差异文件备份工具的示例

    这篇文章主要介绍了C#写差异文件备份工具的示例,帮助大家利用c#备份,管理文件,感兴趣的朋友可以了解下
    2020-10-10
  • C#定时每天00点00分00秒自动重启软件

    C#定时每天00点00分00秒自动重启软件

    这篇文章主要为大家详细介绍了C#定时每天00点00分00秒自动重启软件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-08-08
  • C#多线程系列之async和await用法详解

    C#多线程系列之async和await用法详解

    本文详细讲解了C#多线程中async和await的用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • C#程序如何调用C++ dll详细教程

    C#程序如何调用C++ dll详细教程

    C#和C++形成的DLL有一层天然的屏障,并不能简单地互相调用,想要C#工程调用c++dll,需要先在其外部包裹上clr c++的外壳,本篇文章给大家分享了C#调用C++ dll的详细步骤和方法,有兴趣的朋友可以参考学习下
    2018-07-07
  • WinForm导出文件为Word、Excel、文本文件的方法

    WinForm导出文件为Word、Excel、文本文件的方法

    这篇文章主要介绍了WinForm导出文件为Word、Excel、文本文件的方法,本文直接给出实现代码,代码中包含相应注释,需要的朋友可以参考下
    2015-03-03
  • 比Math类库abs()方法性能更高的取绝对值方法介绍

    比Math类库abs()方法性能更高的取绝对值方法介绍

    这篇文章主要给大家介绍了一种比Math类库abs()方法性能更高的取绝对值方法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-04-04
  • C#实现两接口中同名方法实例分析

    C#实现两接口中同名方法实例分析

    这篇文章主要介绍了C#实现两接口中同名方法,涉及C#接口与方法的相关操作技巧,需要的朋友可以参考下
    2015-05-05

最新评论