WPF开发者QQ群:340500857

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

 yanjinhuawechatW_Feng_aiQ 邀请入群

需备注WPF开发者

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

接着上一篇,进行WriteableBitmap性能优化

修改后运行对比如下:

前(CPU与内存不稳定):

后:

使用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 Margin="4"><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition Width="Auto"/></Grid.ColumnDefinitions><Image Grid.Row="0" Name="imgViewport"/><GroupBox Header="Operation" Grid.Column="1" Margin="0,0,4,0"><Grid><Grid.RowDefinitions><RowDefinition/><RowDefinition/><RowDefinition Height="Auto"/></Grid.RowDefinitions><StackPanel Grid.Row="0" HorizontalAlignment="Center"><CheckBox IsChecked="{Binding IsSave,RelativeSource={RelativeSource AncestorType=local:MainWindow}}"VerticalAlignment="Center" Content="Save" Margin="0,4"/><ComboBox Name="ComboBoxCamera" ItemsSource="{Binding CameraArray,RelativeSource={RelativeSource AncestorType=local:MainWindow}}" SelectedIndex="{Binding CameraIndex,RelativeSource={RelativeSource AncestorType=local:MainWindow}}"SelectionChanged="ComboBoxCamera_SelectionChanged"/></StackPanel><StackPanel Orientation="Horizontal" Grid.Row="2" HorizontalAlignment="Center"><Button Name="btPlay" Content="Play" Style="{StaticResource PrimaryButton}" Click="btPlay_Click" IsEnabled="False"/><Button Name="btStop" Click="btStop_Click" Content="Stop" Margin="4,0"/></StackPanel></Grid></GroupBox></Grid>
</ws:Window>

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

using OpenCvSharp;
using OpenCvSharp.Extensions;
using System;
using System.Collections.Generic;
using System.ComponentModel;
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 VideoWriter videoWriter;private Mat matImage = new Mat();private Thread cameraThread;private Thread writerThread;private CascadeClassifier haarCascade;private WriteableBitmap writeableBitmap;private Rectangle rectangle;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 bool IsSave{get { return (bool)GetValue(IsSaveProperty); }set { SetValue(IsSaveProperty, value); }}public static readonly DependencyProperty IsSaveProperty =DependencyProperty.Register("IsSave", typeof(bool), typeof(MainWindow), new UIPropertyMetadata(IsSaveChanged));private static void IsSaveChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){var mainWindow = d as MainWindow;if (e.NewValue != null){var save = (bool) e.NewValue;if (save)mainWindow.StartRecording();elsemainWindow.StopRecording();}}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();}CreateCamera();writeableBitmap = new WriteableBitmap(capCamera.FrameWidth, capCamera.FrameHeight, 0, 0, System.Windows.Media.PixelFormats.Bgra32, null);imgViewport.Source = writeableBitmap;}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(){capCamera = new VideoCapture(CameraIndex);capCamera.Fps = 30;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;//}));using (var img = BitmapConverter.ToBitmap(matImage)){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));rectangle = new Rectangle(0, 0, img.Width, img.Height);brush.Dispose();g.Dispose();Dispatcher.Invoke(new Action(() =>{WriteableBitmapHelper.BitmapCopyToWriteableBitmap(img, writeableBitmap, rectangle, 0, 0, System.Drawing.Imaging.PixelFormat.Format32bppArgb);}));};Thread.Sleep(100);}}private void StartRecording(){if (capCamera == null){WPFDevelopers.Minimal.Controls.MessageBox.Show("未开启摄像机","提示",MessageBoxButton.OKCancel,MessageBoxImage.Error);return;}var videoFile = System.IO.Path.Combine(System.Environment.CurrentDirectory, "Video");if (!System.IO.Directory.Exists(videoFile))System.IO.Directory.CreateDirectory(videoFile);var currentTime = System.IO.Path.Combine(videoFile, $"{DateTime.Now.ToString("yyyyMMddHHmmsshh")}.avi");videoWriter = new VideoWriter(currentTime, FourCCValues.XVID, capCamera.Fps, new OpenCvSharp.Size(capCamera.FrameWidth, capCamera.FrameHeight));writerThread = new Thread(AddCameraFrameToRecording);writerThread.Start();}private void StopRecording(){if (videoWriter != null && !videoWriter.IsDisposed){videoWriter.Release();videoWriter.Dispose();videoWriter = null;}}private void AddCameraFrameToRecording(){var waitTimeBetweenFrames = 1_000 / capCamera.Fps;var lastWrite = DateTime.Now;while (!videoWriter.IsDisposed){if (DateTime.Now.Subtract(lastWrite).TotalMilliseconds < waitTimeBetweenFrames)continue;lastWrite = DateTime.Now;videoWriter.Write(matImage);}}private void btStop_Click(object sender, RoutedEventArgs e){StopDispose();btStop.IsEnabled = false;}void StopDispose(){if (capCamera != null && capCamera.IsOpened()){capCamera.Dispose();capCamera = null;}if (videoWriter != null && !videoWriter.IsDisposed){videoWriter.Release();videoWriter.Dispose();videoWriter = null;}btPlay.IsEnabled = true;GC.Collect();}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();var writeableBitmap = WriteableBitmapHelper.BitmapToWriteableBitmap(src);return WriteableBitmapHelper.ConvertWriteableBitmapToBitmapImage(writeableBitmap);}protected override void OnClosing(CancelEventArgs e){if(WPFDevelopers.Minimal.Controls.MessageBox.Show("是否关闭系统?", "询问", MessageBoxButton.OKCancel, MessageBoxImage.Question) != MessageBoxResult.OK) {e.Cancel = true;return;}}protected override void OnClosed(EventArgs e){StopDispose();}private void btPlay_Click(object sender, RoutedEventArgs e){btPlay.IsEnabled = false;btStop.IsEnabled = true;CreateCamera();}}
}

三、WriteableBitmapHelper.cs代码如下。

using System.IO;
using System.Windows;
using System.Windows.Media.Imaging;namespace OpenCVSharpExample
{public class WriteableBitmapHelper{//将Bitmap 转换成WriteableBitmap public static WriteableBitmap BitmapToWriteableBitmap(System.Drawing.Bitmap src){var wb = CreateCompatibleWriteableBitmap(src);System.Drawing.Imaging.PixelFormat format = src.PixelFormat;if (wb == null){wb = new WriteableBitmap(src.Width, src.Height, 0, 0, System.Windows.Media.PixelFormats.Bgra32, null);format = System.Drawing.Imaging.PixelFormat.Format32bppArgb;}BitmapCopyToWriteableBitmap(src, wb, new System.Drawing.Rectangle(0, 0, src.Width, src.Height), 0, 0, format);return wb;}//创建尺寸和格式与Bitmap兼容的WriteableBitmappublic static WriteableBitmap CreateCompatibleWriteableBitmap(System.Drawing.Bitmap src){System.Windows.Media.PixelFormat format;switch (src.PixelFormat){case System.Drawing.Imaging.PixelFormat.Format16bppRgb555:format = System.Windows.Media.PixelFormats.Bgr555;break;case System.Drawing.Imaging.PixelFormat.Format16bppRgb565:format = System.Windows.Media.PixelFormats.Bgr565;break;case System.Drawing.Imaging.PixelFormat.Format24bppRgb:format = System.Windows.Media.PixelFormats.Bgr24;break;case System.Drawing.Imaging.PixelFormat.Format32bppRgb:format = System.Windows.Media.PixelFormats.Bgr32;break;case System.Drawing.Imaging.PixelFormat.Format32bppPArgb:format = System.Windows.Media.PixelFormats.Pbgra32;break;case System.Drawing.Imaging.PixelFormat.Format32bppArgb:format = System.Windows.Media.PixelFormats.Bgra32;break;default:return null;}return new WriteableBitmap(src.Width, src.Height, 0, 0, format, null);}//将Bitmap数据写入WriteableBitmap中public static void BitmapCopyToWriteableBitmap(System.Drawing.Bitmap src, WriteableBitmap dst, System.Drawing.Rectangle srcRect, int destinationX, int destinationY, System.Drawing.Imaging.PixelFormat srcPixelFormat){var data = src.LockBits(new System.Drawing.Rectangle(new System.Drawing.Point(0, 0), src.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, srcPixelFormat);dst.WritePixels(new Int32Rect(srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height), data.Scan0, data.Height * data.Stride, data.Stride, destinationX, destinationY);src.UnlockBits(data);}public static BitmapImage ConvertWriteableBitmapToBitmapImage(WriteableBitmap wbm){BitmapImage bmImage = new BitmapImage();using (MemoryStream stream = new MemoryStream()){PngBitmapEncoder encoder = new PngBitmapEncoder();encoder.Frames.Add(BitmapFrame.Create(wbm));encoder.Save(stream);bmImage.BeginInit();bmImage.CacheOption = BitmapCacheOption.OnLoad;bmImage.StreamSource = stream;bmImage.EndInit();bmImage.Freeze();}return bmImage;}}
}

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 展示视频修改为WriteableBitmap相关推荐

  1. 视频消重软件百度云 小视频修改md5

             视频消重软件百度云 小视频修改md5          微网剧每集内的场景数量.镜头切换频率非常重要,标准将在后续的文章中深度分析.                      在短视 ...

  2. 视频修改伪原创 自媒体视频搬运去md5

             视频修改伪原创 自媒体视频搬运去md5          过去一周,抖音先被曝因TikTok导致公司亏损12亿美元,又短暂屏蔽腾讯系游戏的关键词搜索结果,一项直指抖音强投放造成的财务 ...

  3. 抖音如何快速上热门 手机md5视频修改工具下载

              抖音如何快速上热门 手机md5视频修改工具下载          点赞量+评论量+ 转发量+完播率,而多家微网剧剧组已经形成了自有IP矩阵,将追剧观众转化为粉丝,并通过招商.打赏等 ...

  4. Bootstrap4+MySQL前后端综合实训-Day09-AM【项目功能展示视频、小组汇报PPT、项目介绍】

    [Bootstrap4前端框架+MySQL数据库]前后端综合实训[10天课程 博客汇总表 详细笔记][附:实训所有代码] 目   录 项目功能展示视频(视频地址:https://live.csdn.n ...

  5. ffmpeg命令_使用ffmpeg命令为多个短视频修改视频备注说明

    今天主要给大家讲一下使用视频剪辑高手中的ffmpeg命令为多个短视频修改备注说明的详细步骤,有需要和感兴趣的宝贝们可以跟随小编一起来试试. 收集视频 将需要剪辑的短视频保存到同一文件夹上 进入软件 双 ...

  6. 抖音一般多久能上热门 视频修改MD5工具

              抖音一般多久能上热门 视频修改MD5工具          对于广大的内容创业者来讲,短视频行业无疑是很后一波红利.以抖音.快手为代表的短视频平台的崛起说明作为一种全新的内容形式, ...

  7. 短视频批量伪原创破解 苹果手机md5视频修改工具下载

             短视频批量伪原创破解 苹果手机md5视频修改工具下载          对平台来讲,拥有下载量就是抓紧了企业的命脉,而对网红来讲,粉丝的多少决定了个人的金脉             ...

  8. elementui 双击el-table表格展示输入框修改数据

    参考:element ui 双击表格展示输入框 修改数据_7ing酒的博客-CSDN博客_双击输入框展示: 功能:就是一个简单的table表格 通过双击某一项 进行修改.(其实就是双击之后变成一个in ...

  9. 视频伪原创批量处理工具 md5视频 修改器

             视频伪原创批量处理工具 md5视频 修改器        这是因为文章形式的内容跳过率自然很高..       视频伪原创批量处理工具 md5视频 修改器 自媒体运营技巧:短视频优质 ...

最新文章

  1. 《数据科学家养成手册》第十一章------算法学1(穷举,分治,回溯,贪心,迭代)
  2. stl-unique()函数去重
  3. MySQL调优(三):索引基本实现原理及索引优化,哈希索引 / 组合索引 / 簇族索引等
  4. SGU 117 Counting
  5. C#刷遍Leetcode面试题系列连载(1) - 入门与工具简介
  6. MySQL的四种事务隔离级别实践
  7. 使用IAR在线调试功能显示数据变化曲线
  8. AJAX请求时status返回状态明细表 readyState的五种状态
  9. 软件工程期末考试复习(二)
  10. HCIE-Security心得
  11. 新版犀牛书该不该入手?
  12. 数据资料网站_更新......
  13. 软件测试的目的、原则及流程
  14. 配置的代理服务器未响应解决方法
  15. postman-批量导入数据
  16. python数据类型(一)
  17. 使用xom实现xml文件数据的查找,删除,修改(转载)
  18. 虚假新闻检测的论文阅读笔记——sigir2021:User Preference-aware Fake News Detection
  19. IS210AEBIH3BEC隔离器用于变压器等高压设备
  20. matlab饼图正圆,怎样用matlab画饼图

热门文章

  1. 添加Chrome插件(Github上下载的压缩文件)
  2. 【转】Asp.net控件开发学习笔记整理篇 - 数据回传
  3. 鼠标手势识别 [Flash]
  4. c++ map用法_Python的 5 种高级用法,效率提升没毛病
  5. 画闭合的多边形 - HTML5 Canvas 作图
  6. Leetcode400Nth Digit第N个数字
  7. c#中的奇异递归模式
  8. Ajax:一种网页开发技术(Asynchronous Javascript + XML)
  9. kdbchk: the amount of space used is not equal to block size
  10. 在主窗体中打开一个新子窗体,如果已有子窗体,则激活它,而不打开新的。...