最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

WPF實(shí)現(xiàn)獲取攝像頭幀圖的代碼示例

 更新時(shí)間:2024年02月01日 08:46:19   作者:黑白分明  
這篇文章主要介紹了如何利用WPF實(shí)現(xiàn)獲取攝像頭幀圖的代碼示例,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定幫助,感興趣的可以參考一下

一.前言

項(xiàng)目需求:支持uvc的攝像頭,取出其畫(huà)面幀圖,進(jìn)行相關(guān)疊加,并重新展示在image控件上

環(huán)境:用的是.net framework 4.8.1 。 當(dāng)然.net6 也支持

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

備注:winform和uwp都可以進(jìn)行參考

二.項(xiàng)目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(() =>
            {
				//這里就可以對(duì)圖片進(jìn)行相關(guān)疊加操作,再賦值給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 方法創(chuàng)建 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)
        {
            //這里默認(rèn)選擇設(shè)備列表[0],如果是筆記本外接usb攝像頭要取數(shù)組[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()停止信號(hào)就行,使用stop()方法會(huì)導(dǎo)致更新線程卡死
            videoSource.SignalToStop();
            isCapturing = false;
        }
    }
}
}

上面這部分代碼就是取圖片幀的方法,基本延遲在200ms左右,比vlc插件調(diào)取更快。

三.需要定制化下,如何優(yōu)化此代碼

demo所展示的只是基本取圖,如要在取圖的基礎(chǔ)上 疊加定制化內(nèi)容并不影響取圖效率,該如何考慮?

本人分享一個(gè)解決辦法:

首先不使用Bitmap 類(lèi)型,改為SKBitmap類(lèi)型———SKBitmap 使用的是 SkiaSharp的庫(kù)

把Bitmap轉(zhuǎn)成SKBitmap類(lèi)型

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

需要定制化的內(nèi)容 使用SKBitmap類(lèi)型的指針進(jìn)行處理,速度更快——此處根據(jù)項(xiàng)目本身進(jìn)行處理

定制后的SKBitmap類(lèi)型內(nèi)容再轉(zhuǎn)換成WriteableBitmap類(lèi)型,使用WritePixels方法進(jìn)行構(gòu)成,video.source可以進(jìn)行讀取

//參考例子
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);

這個(gè)定制轉(zhuǎn)換的效果與demo展示的效率相當(dāng)

四. demo展示

以上就是WPF實(shí)現(xiàn)獲取攝像頭幀圖的代碼示例的詳細(xì)內(nèi)容,更多關(guān)于WPF取攝像頭幀圖的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • c#枚舉值增加特性說(shuō)明(推薦)

    c#枚舉值增加特性說(shuō)明(推薦)

    這篇文章主要介紹了c#枚舉值增加特性說(shuō)明(推薦),需要的朋友可以參考下
    2017-05-05
  • 一個(gè)可攜帶附加消息的增強(qiáng)消息框MessageBoxEx

    一個(gè)可攜帶附加消息的增強(qiáng)消息框MessageBoxEx

    一個(gè)可攜帶附加消息的增強(qiáng)消息框MessageBoxEx分享給大家,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • c#消息提示框messagebox的詳解及使用

    c#消息提示框messagebox的詳解及使用

    這篇文章主要介紹了c#消息提示框messagebox的詳解及使用的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • 解析如何使用反射調(diào)用類(lèi)型成員 方法,字段,屬性

    解析如何使用反射調(diào)用類(lèi)型成員 方法,字段,屬性

    本篇文章是對(duì)使用反射調(diào)用類(lèi)型成員 方法,字段,屬性進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • 使用C#發(fā)送Http請(qǐng)求實(shí)現(xiàn)模擬登陸實(shí)例

    使用C#發(fā)送Http請(qǐng)求實(shí)現(xiàn)模擬登陸實(shí)例

    本文主要介紹了使用C#發(fā)送Http請(qǐng)求實(shí)現(xiàn)模擬登陸實(shí)例,模擬登陸的原理簡(jiǎn)單,想要了解的朋友可以了解一下。
    2016-10-10
  • C#數(shù)據(jù)結(jié)構(gòu)與算法揭秘二 線性結(jié)構(gòu)

    C#數(shù)據(jù)結(jié)構(gòu)與算法揭秘二 線性結(jié)構(gòu)

    本文中,我們討論了什么是線性結(jié)構(gòu),線性結(jié)構(gòu)有哪些特點(diǎn),并且詳細(xì)介紹了一個(gè)最簡(jiǎn)單線性結(jié)構(gòu)順序表,并且通過(guò)源代碼對(duì)她進(jìn)行一些列的分析,最后還舉了兩個(gè)例子,讓我們更好的理解順序表
    2012-11-11
  • C#實(shí)現(xiàn)批量壓縮和解壓縮的示例代碼

    C#實(shí)現(xiàn)批量壓縮和解壓縮的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用C#實(shí)現(xiàn)批量壓縮和解壓縮的功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下
    2022-12-12
  • C#使用Tesseract進(jìn)行中文識(shí)別的詳細(xì)步驟

    C#使用Tesseract進(jìn)行中文識(shí)別的詳細(xì)步驟

    文章介紹了如何在C#中使用Tesseract進(jìn)行中文識(shí)別,包括環(huán)境準(zhǔn)備、安裝NuGet包、配置語(yǔ)言數(shù)據(jù)文件、基本使用代碼、核心API詳解、高級(jí)功能與優(yōu)化等步驟,需要的朋友可以參考下
    2026-03-03
  • C#集合之字典的用法

    C#集合之字典的用法

    這篇文章介紹了C#集合之字典的用法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • C#?SQLite庫(kù)使用技巧

    C#?SQLite庫(kù)使用技巧

    SQLite是一個(gè)開(kāi)源、免費(fèi)的小型RDBMS(關(guān)系型數(shù)據(jù)庫(kù)),能獨(dú)立運(yùn)行、無(wú)服務(wù)器、零配置、支持事物,用C實(shí)現(xiàn),內(nèi)存占用較小,支持絕大數(shù)的SQL92標(biāo)準(zhǔn)。下面跟隨小編一起看下C#?SQLite庫(kù)使用
    2022-01-01

最新評(píng)論

开化县| 麻城市| 平利县| 商丘市| 长乐市| 廉江市| 彭水| 江口县| 金秀| 华阴市| 潜江市| 武强县| 临城县| 稻城县| 武川县| 信阳市| 大渡口区| 伊川县| 西青区| 舒城县| 余干县| 乐昌市| 阿克苏市| 德化县| 萝北县| 张家港市| 长沙县| 罗定市| 徐闻县| 寿宁县| 奉化市| 东乡族自治县| 武汉市| 任丘市| 永和县| 叶城县| 阳山县| 澜沧| 慈溪市| 建始县| 华坪县|