WPF 实现调用本机摄像头~

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF 实现调用本机摄像头~相关的知识,希望对你有一定的参考价值。

WPF开发者QQ群:340500857

       由于微信群人数太多入群请添加小编微信号

 yanjinhuawechatW_Feng_aiQ 邀请入群

 需备注WPF开发者 

  PS:有更好的方式欢迎推荐。

  接着很久前的上一篇

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

使用NuGet如下:

01

代码如下

一、创建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();
        


    

02


效果预览

鸣谢素材提供者屈越

源码地址如下

Github:https://github.com/WPFDevelopersOrg

https://github.com/WPFDevelopersOrg/OpenCVSharpExample

Gitee:https://gitee.com/WPFDevelopersOrg

WPF开发者QQ群: 340500857 

Github:https://github.com/WPFDevelopersOrg

出处:https://www.cnblogs.com/yanjinhua

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

转载请著名作者 出处 https://github.com/WPFDevelopersOrg

扫一扫关注我们,

更多知识早知道!

点击阅读原文可跳转至源代码

以上是关于WPF 实现调用本机摄像头~的主要内容,如果未能解决你的问题,请参考以下文章

适用于 IOS 的摄像机本机扩展

基于opencv,开发摄像头播放程序

javaCV开发详解之10:基于dshow调用windows摄像头视频和音频,想要获取屏幕画面首选gdigrab

如何在 ibm worklight 中打开本机摄像头

WPF 的摄像头控件VideoCaptureElement 浅谈

C#调用摄像头并访问西门子PLC以及在车间的可能性应用