WPF实现调用本机摄像头的示例代码
作者:驚鏵 时间:2023-03-15 15:40:24
此项目使用了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
来源:https://mp.weixin.qq.com/s/j-B_lq7Vap2w6eY7g2sozg
标签:WPF,摄像头
0
投稿
猜你喜欢
C#获取网页源代码的方法
2023-06-19 05:43:44
Java实现简单的五子棋小游戏
2023-11-25 07:36:13
Java的封装类和装箱拆箱详解
2023-09-20 22:41:22
java 键盘输入一个数,输出数组中指定元素的示例
2023-11-24 20:31:14
spring框架cacheAnnotation缓存注释声明解析
2022-04-14 17:13:05
SpringBoot浅析安全管理之OAuth2框架
2022-10-12 17:17:04
java与JSON数据的转换实例详解
2022-07-03 22:48:25
Java基础之位运算知识总结
2022-09-10 17:48:43
JAVA实现账户取款和存款操作
2023-08-22 16:31:45
Java远程连接Linux服务器并执行命令及上传文件功能
2023-01-28 14:03:31
Java中的zookeeper常用命令详解
2022-12-07 05:46:35
Java中使用StackWalker和Stream API进行堆栈遍历
2023-04-12 11:29:07
Spring集成MyBatis 及Aop分页的实现代码
2022-01-06 14:30:47
java 中 poi解析Excel文件版本问题解决办法
2023-11-15 16:49:45
详细了解JAVA NIO之Buffer(缓冲区)
2022-08-18 00:59:28
图文并茂讲解RocketMQ消息类别
2023-06-11 07:59:41
java开发之MD5加密算法的实现
2022-05-13 23:44:35
Java 格式化输出JSON字符串的2种实现操作
2023-11-13 09:41:10
Java实现树形结构的示例代码
2023-07-30 01:05:19
Java如何提供给第三方使用接口方法详解
2022-07-22 19:59:19