WPF实现获取摄像头帧图的代码示例

 更新时间:2024年02月01日 08:46:19   作者:黑白分明  
这篇文章主要介绍了如何利用WPF实现获取摄像头帧图的代码示例,文中的示例代码讲解详细,对我们学习或工作有一定帮助,感兴趣的可以参考一下

一.前言

项目需求:支持uvc的摄像头,取出其画面帧图,进行相关叠加,并重新展示在image控件上

环境:用的是.net framework 4.8.1 。 当然.net6 也支持

使用的第三方插件:AForge.Video.DirectShow

备注:winform和uwp都可以进行参考

二.项目demo代码

MainWindow.xaml部分

<Window x:Class="WpfApp2.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:local="clr-namespace:WpfApp2"
xmlns:vlc="clr-namespace:LibVLCSharp.WPF;assembly=LibVLCSharp.WPF"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"> <Grid> <Image x:Name="video" Margin="0,40,0,0"/> <Button x:Name="StartButton" Content="start" HorizontalAlignment="Left" Margin="39,11,0,0" VerticalAlignment="Top" Click="StartButton_event"/> <Button x:Name="StopButton" Content="stop" HorizontalAlignment="Left" Margin="88,10,0,0" VerticalAlignment="Top" Click="StopButton_event"/> </Grid> </Window>

MainWindow.cs部分

using AForge.Video;
using AForge.Video.DirectShow;
using LibVLCSharp.Shared;
using LoggerServiceFK;
using SkiaSharp;
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Drawing;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop;
using System.Windows.Media.Imaging;

namespace WpfApp2 {
/// 
/// MainWindow.xaml 的交互逻辑
/// 
public partial class MainWindow : Window
{
private VideoCaptureDevice videoSource;
private bool isCapturing = false;

  public MainWindow()
    {
        InitializeComponent(); 
    }

    private void VideoSource_NewFrame(object sender, NewFrameEventArgs eventArgs)
    {
        if (isCapturing)
        {
            // Convert AForge.NET Framework's Bitmap to WPF's BitmapSource
            Bitmap aforgeBitmap = (Bitmap)eventArgs.Frame.Clone();
         
            // Display the video frame in an Image control
            Dispatcher.Invoke(() =>
            {
				//这里就可以对图片进行相关叠加操作,再赋值给source				
                video.Source = Convert(aforgeBitmap);
            });
        }
    }

    public static BitmapSource Convert(Bitmap bitmap)
    {
        if (bitmap == null)
        {
            throw new ArgumentNullException(nameof(bitmap));
        }

        // 获取 Bitmap 的 HBitmap 句柄
        IntPtr hBitmap = bitmap.GetHbitmap();

        // 使用 CreateBitmapSourceFromHBitmap 方法创建 BitmapSource
        BitmapSource bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(
            hBitmap,
            IntPtr.Zero,
            Int32Rect.Empty,
            BitmapSizeOptions.FromEmptyOptions());

        // 释放 Bitmap 的 HBitmap 句柄
        NativeMethods.DeleteObject(hBitmap);

        return bitmapSource;
    }

    private static class NativeMethods
    {
        [System.Runtime.InteropServices.DllImport("gdi32.dll")]
        [return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)]
        public static extern bool DeleteObject(IntPtr hObject);
    }
    private void StartButton_event(object sender, RoutedEventArgs e)
    {
		//这里获取usb摄像头的地方
        FilterInfoCollection videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
        if (videoDevices.Count > 0)
        {
            //这里默认选择设备列表[0],如果是笔记本外接usb摄像头要取数组[1]
            videoSource = new VideoCaptureDevice(videoDevices[0].MonikerString);
            videoSource.NewFrame += VideoSource_NewFrame;
            videoSource.Start();

            isCapturing = true;
        }
    }

    private void StopButton_event(object sender, RoutedEventArgs e)
    {
        if (videoSource != null && videoSource.IsRunning)
        {
		//SignalToStop()停止信号就行,使用stop()方法会导致更新线程卡死
            videoSource.SignalToStop();
            isCapturing = false;
        }
    }
}
}

上面这部分代码就是取图片帧的方法,基本延迟在200ms左右,比vlc插件调取更快。

三.需要定制化下,如何优化此代码

demo所展示的只是基本取图,如要在取图的基础上 叠加定制化内容并不影响取图效率,该如何考虑?

本人分享一个解决办法:

首先不使用Bitmap 类型,改为SKBitmap类型———SKBitmap 使用的是 SkiaSharp的库

把Bitmap转成SKBitmap类型

		var CurrentBitmap = new SKBitmap(640,480);
		CurrentBitmap=aforgeBitmap.ToSKBitmap();

需要定制化的内容 使用SKBitmap类型的指针进行处理,速度更快——此处根据项目本身进行处理

定制后的SKBitmap类型内容再转换成WriteableBitmap类型,使用WritePixels方法进行构成,video.source可以进行读取

//参考例子
var writeableBitmap = new WriteableBitmap(640, 480, 96, 96, PixelFormats.Bgr32, null);
writeableBitmap.WritePixels(new Int32Rect(0, 0, skbitmap.Width, skbitmap.Height), skbitmap.GetPixels(), skbitmap.RowBytes * skbitmap.Height, skbitmap.RowBytes);

这个定制转换的效果与demo展示的效率相当

四. demo展示

以上就是WPF实现获取摄像头帧图的代码示例的详细内容,更多关于WPF取摄像头帧图的资料请关注脚本之家其它相关文章!

相关文章

  • C# 类型转换(隐式类型,显式类型,自定义类型)

    C# 类型转换(隐式类型,显式类型,自定义类型)

    本文详细介绍了C#中的类型转换,包括隐式类型转换和显式类型转换(强制类型转换),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-11-11
  • WinForm窗体间传值的方法

    WinForm窗体间传值的方法

    这篇文章主要介绍了WinForm窗体间传值的方法,包括了静态变量、公共变量、共有属性等方式,是非常实用的技巧,需要的朋友可以参考下
    2014-11-11
  • c#实现万年历示例分享 万年历农历查询

    c#实现万年历示例分享 万年历农历查询

    这篇文章主要介绍了c#实现万年历的方法,可以显示农历、节气、节日、星座、星宿、属相、生肖、闰年月、时辰,大家参考使用吧
    2014-01-01
  • WinForm实现程序一段时间不运行自动关闭的方法

    WinForm实现程序一段时间不运行自动关闭的方法

    这篇文章主要介绍了WinForm实现程序一段时间不运行自动关闭的方法,涉及WinForm计时器及进程操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-09-09
  • 解决WPF附加属性的Set函数不调用的问题

    解决WPF附加属性的Set函数不调用的问题

    这篇文章介绍了解决WPF附加属性的Set函数不调用的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • C#中执行批处理文件(*.bat)的方法代码

    C#中执行批处理文件(*.bat)的方法代码

    本文介绍一下在C#中执行批处理文件(*.bat)的方法。
    2013-03-03
  • Task提高异步执行效率技巧

    Task提高异步执行效率技巧

    这篇文章介绍了Task提高异步执行效率的技巧,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • C#加解密之AES算法的实现

    C#加解密之AES算法的实现

    一般我们来说呢,对于加密,我们分为可逆和不可逆。可逆加密又可分为对称加密(AES、DES等)和非对称加密(RSA),还有就是一些编码加密等(BASE64);不可逆的呢,大部分又都称为摘要算法(MD5、SHA)。本文将用C#实现AES算法,需要的可以参考一下
    2022-08-08
  • C# wpf实现控件刷新的示例代码

    C# wpf实现控件刷新的示例代码

    这篇文章主要为大家详细介绍了C# wpf实现控件刷新的相关知识,文中的示例代码讲解详细,具有一定的借鉴价值,需要的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • C#多线程Thread使用示例详解

    C#多线程Thread使用示例详解

    这篇文章主要为大家详细介绍了C#多线程Thread使用示例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07

最新评论