C# WPF 显示图片和视频显示 EmuguCv、AForge.Net测试

C# WPF 显示图片和视频显示 EmuguCv、AForge.Net测试
原文:C# WPF 显示图片和视频显示 EmuguCv、AForge.Net测试

WPF 没有用到 PictureBox, 而是用Image代替.

下面我试着加载显示一个图片 。

XAML

<Image x:Name="srcImg"Width="400"Height="300"></Image>

CS Attempt 1:

Image<Bgr,Byte>My_Image=newImage<Bgr,byte>(Openfile.FileName);
srcImg.Source=My_Image.ToBitmap();

Error Message

Cannot implicitly convert type 'System.Drawing.Bitmap' 
to 'System.Windows.Media.ImageSource'

CS Attempt 2:

Image<Bgr,Byte>My_Image=newImage<Bgr,byte>(Openfile.FileName);
srcImg.Source=newBitmapImage(My_Image);

Error Message

Error1The best overloaded method match for'System.Windows.Media.Imaging.BitmapImage.BitmapImage(System.Uri)' has some invalid arguments  
Error2Argument1: cannot convert from'Emgu.CV.Image<Emgu.CV.Structure.Bgr,byte>' to 'System.Uri'

解决方法:

Image<Bgr, Byte> My_Image = new Image<Bgr, byte>(Openfile.FileName);
srcImg.Source = BitmapSourceConvert.ToBitmapSource(myImage);
public static class BitmapSourceConvert
{[DllImport("gdi32")]private static extern int DeleteObject(IntPtr o);public static BitmapSource ToBitmapSource(IImage image){using (System.Drawing.Bitmap source = image.Bitmap){IntPtr ptr = source.GetHbitmap();BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ptr,IntPtr.Zero,Int32Rect.Empty,System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());DeleteObject(ptr);return bs;}}
}

 

 测试:

 Bitmap bm = (Bitmap)Bitmap.FromFile(@"D:\my_testfiles\Main.png");int count = 10000000;for (int i = 0; i < count; i++){Commons.BitMapToImageSource(bm.Clone() as Bitmap);}
 
结果:

当循环 1527次,  耗时 00:00:17.8860231后  报错。


ErrorTrace:
 at System.Drawing.Bitmap.GetHbitmap(Color background)at System.Drawing.Bitmap.GetHbitmap()at SimpleClient.Commons.BitMapToImageSource(Bitmap bitmap) in D:\my_svn\universal-project\SimpleClient\Program.cs:line 165
 

ErrorMessage:

system.OutOfMemoryException: Out of memory.

改进:

写一个视频显示控件,内部实现显示Bitmap转换成BitmapSource。为控件Source开辟一块内存控件,然后一直刷新。首先我们使用EmuguCV里面的Capture。
控件继承Image、IDisposable接口并开放一个属性
VideoSource
代码如下:
    public class CapPlayer : Image, IDisposable{private Capture videoSource;public Capture VideoSource{set{if (value != null){this.videoSource = value;this.LaodCapPlayer();}}}private InteropBitmap bitmapSource;private IntPtr map;private IntPtr section;public CapPlayer(){Application.Current.Exit += new ExitEventHandler(Current_Exit);}private void LaodCapPlayer(){videoSource.ImageGrabbed += new Capture.GrabEventHandler(videoSource_ImageGrabbed);videoSource.Start();uint pcount = (uint)(videoSource.Width * videoSource.Height * PixelFormats.Bgr32.BitsPerPixel / 8);section = CreateFileMapping(new IntPtr(-1), IntPtr.Zero, 0x04, 0, pcount, null);map = MapViewOfFile(section, 0xF001F, 0, 0, pcount);bitmapSource = Imaging.CreateBitmapSourceFromMemorySection(section, (int)videoSource.Width, (int)videoSource.Height, PixelFormats.Bgr32,(int)(videoSource.Width * PixelFormats.Bgr32.BitsPerPixel / 8), 0) as InteropBitmap;this.Source = bitmapSource;}void videoSource_ImageGrabbed(object sender, EventArgs e){Capture camera = sender as Capture;var frame = camera.RetrieveBgrFrame().Bitmap;if (this.Dispatcher != null){this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, (SendOrPostCallback)delegate{if (map != IntPtr.Zero){try{System.Drawing.Imaging.BitmapData bmpData = frame.LockBits(new System.Drawing.Rectangle(0, 0, (int)videoSource.Width, (int)videoSource.Height),System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppRgb);/* Get the pointer to the pixels */IntPtr pBmp = bmpData.Scan0;int srcStride = bmpData.Stride;int pSize = srcStride * (int)videoSource.Height;CopyMemory(map, pBmp, pSize);frame.UnlockBits(bmpData);}catch (Exception ex){Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Write(ex, "Info", 0);}}if (bitmapSource != null){bitmapSource.Invalidate();}}, null);}if (captureLock){try{lock (mutCurrentImg){camera.RetrieveBgrFrame().Save(imageFileName);}}catch (System.Exception ex){Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Write(ex, "Info", 0);}captureLock = false;}}void Current_Exit(object sender, ExitEventArgs e){this.Dispose();}object mutCurrentImg = new object();bool captureLock = false;string imageFileName = string.Empty;public void ImaggingCapture(string imageFileName){this.imageFileName = imageFileName;this.captureLock = true;}#region IDisposable Memberspublic void Dispose(){if (videoSource != null)videoSource.Stop();Application.Current.Exit -= new ExitEventHandler(Current_Exit);}#endregion[DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory")]private static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length);[DllImport("kernel32.dll", SetLastError = true)]static extern IntPtr CreateFileMapping(IntPtr hFile, IntPtr lpFileMappingAttributes, uint flProtect, uint dwMaximumSizeHigh, uint dwMaximumSizeLow, string lpName);[DllImport("kernel32.dll", SetLastError = true)]static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap);}
 

测试结果:无异常,但是发现比较占用CPU 10%左右,内存 122M 左右,线程数32.

感觉不太理想CPU占用太多,我们把EmuguCV的Capture改为AForge.NEt的VideoCaptureDevice,代码如下:

    public class CapPlayer : Image, IDisposable{private  VideoCaptureDevice videoSource;private InteropBitmap bitmapSource;private IntPtr map;private IntPtr section;public CapPlayer(){Application.Current.Exit += new ExitEventHandler(Current_Exit);this.Loaded += new RoutedEventHandler(CapPlayer_Loaded);videoSource = new VideoCaptureDevice(@"device:pnp:\\?\usb#vid_0ac8&pid_305b#5&ee85354&0&2#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global");  }void CapPlayer_Loaded(object sender, RoutedEventArgs e){videoSource.NewFrame += new NewFrameEventHandler(videoSource_NewFrame);videoSource.Start();uint pcount = (uint)(this.Width * this.Height * PixelFormats.Bgr32.BitsPerPixel / 8);section = CreateFileMapping(new IntPtr(-1), IntPtr.Zero, 0x04, 0, pcount, null);map = MapViewOfFile(section, 0xF001F, 0, 0, pcount);bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromMemorySection(section, (int)this.Width, (int)this.Height, PixelFormats.Bgr32,(int)(this.Width * PixelFormats.Bgr32.BitsPerPixel / 8), 0) as InteropBitmap;this.Source = bitmapSource;}void Current_Exit(object sender, ExitEventArgs e){this.Dispose();}object mutCurrentImg = new object();bool captureLock = false;string imageFileName = string.Empty;public void ImaggingCapture(string imageFileName){this.imageFileName = imageFileName;this.captureLock = true;}private void videoSource_NewFrame(object sender, NewFrameEventArgs eventArgs){//eventArgs.Frame.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);if (this.Dispatcher != null){this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, (SendOrPostCallback)delegate{if (map != IntPtr.Zero){System.Drawing.Imaging.BitmapData bmpData = eventArgs.Frame.LockBits(new System.Drawing.Rectangle(0, 0, (int)this.Width, (int)this.Height),System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppRgb);/* Get the pointer to the pixels */IntPtr pBmp = bmpData.Scan0;int srcStride = bmpData.Stride;int pSize = srcStride * (int)this.Height;CopyMemory(map, pBmp, pSize);eventArgs.Frame.UnlockBits(bmpData);}if (bitmapSource != null){bitmapSource.Invalidate();}}, null);}if (captureLock){try{lock (mutCurrentImg){eventArgs.Frame.Save(imageFileName);}}catch (System.Exception ex){}captureLock = false;}}#region IDisposable Memberspublic void Dispose(){if (videoSource != null)videoSource.SignalToStop();}#endregion[DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory")]private static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length);[DllImport("kernel32.dll", SetLastError = true)]static extern IntPtr CreateFileMapping(IntPtr hFile, IntPtr lpFileMappingAttributes, uint flProtect, uint dwMaximumSizeHigh, uint dwMaximumSizeLow, string lpName);[DllImport("kernel32.dll", SetLastError = true)]static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap);}

 

测试结果:无异常,但是发现占用CPU 1%左右,内存 72M 左右,线程数28. 是不是比较理想呢!!

 

CPU

内存

线程数

EmuguCV

10%左右

122M左右

32

Aforge.Net

1%左右

72M左右

28

 

我的电脑配置.

摄像头:FrameRate 30,Width 320 Height 240.

电脑型号 戴尔 Precision WorkStation T3400 Tower
操作系统 Windows 7 旗舰版 32位 SP1 ( DirectX 11 )
处理器 英特尔 酷睿2 双核 E8400 @ 3.00GHz
主板 戴尔 0HY553 (英特尔 X38/X48 Express 芯片组 - ICH9R)
内存 4 GB ( 海力士 DDR2 800MHz / 金士顿 DDR2 667MHz )
主硬盘 西数 WDC WD3200AAKS-75L9A0 ( 320 GB / 7200 转/分 )
显卡 Nvidia Quadro NVS 290 ( 256 MB / Nvidia )
显示器 戴尔 DELA04A DELL E170S ( 17.1 英寸 )
光驱 飞利浦-建兴 DVD-ROM DH-16D5S DVD光驱
声卡 Analog Devices AD1984 @ 英特尔 82801I(ICH9) 高保真音频
网卡 博通 BCM5754 NetXtreme Gigabit Ethernet / 戴尔

gdi32.dll

系统文件gdi32.dll是存放在Windows系统文件夹中的重要文件,通常情况下是在安装操作系统过程中自动创建的,对于系统正常运行来说至关重要。除非用户电脑被木马病毒、或是流氓软件篡改导致出现gdi32.dll丢失、缺失损坏等弹窗现象,否则不建议用户对该类文件(gdi32.dll)进行随意的修改。

gdi32.dll是Windows GDI图形用户界面相关程序,包含的函数用来绘制图像和显示文字。

posted on 2018-10-20 14:36 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/9821618.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/352477.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一般一个前端项目完成需要多久_一种按周迭代的敏捷式项目管理方法

项目管理有很多理论&#xff0c;并且相关内容非常丰富&#xff0c;例如经典的项目管理的教材《项目管理&#xff1a;计划、进度和控制的系统方法》&#xff0c;字数达到了100万字。但是从源头来说&#xff0c;经典项目管理理论都是源自于对生产项目的过程中需要的管理的总结。对…

excel连接mysql 数据库

最近做个项目需要对收集到的数据进行实时刷新&#xff0c;原先考虑让获得的数据之间输出到txt文本&#xff0c;然后又文本导入到数据库&#xff0c;但是txt在修改查找的时候要把数据都读入到内存在进行相关改动&#xff0c;这样就很耗内存&#xff0c;而且文件占用率比较高&…

python jieba库下载_Python中jieba库安装步骤及失败原因解析

Python 中 jieba 库安装步骤及失败原因解析 作为计算机小白&#xff0c; Python 的流行也让我蠢蠢欲动&#xff0c; 在请教计算机 专业同学后&#xff0c;开始上网课自学 Python 基础知识。今天老师简单的一 句话“在命令行去运行 pip install jieba 的指令”安装 jieba 库&…

开放源代码库指南

微软.NET开发团队在博客上&#xff08;https://blogs.msdn.microsoft.com/dotnet/2018/10/15/guidance-for-library-authors/&#xff09;刚刚发布了.NET Library Guidance的第一个版本。这是一系列全新的文章&#xff0c;指导你为.NET创建高质量代码库。该指南包含我们已确定的…

[Microsoft][ODBC 驱动程序管理器] 在指定的 DSN 中,驱动程序和应用程序之间的体系结构不匹配

在数据库和excel对接中有可能会出现错误“[Microsoft][ODBC 驱动程序管理器] 在指定的 DSN 中&#xff0c;驱动程序和应用程序之间的体系结构不匹配” 本人发生这种情况的是在excel 在选定数据连接向导的时候&#xff0c;这是驱动程序和excel的体系结构不匹配&#xff1b; 环…

python程序写诗_python写的简单发送邮件的脚本

近来有些东西需要监控报警发邮件&#xff0c;然后在网上找了点材料&#xff0c;自己写了一个简单发送邮件的脚本&#xff0c;主要就是运用python的smtplib模块&#xff0c;分享给大家看一下&#xff1a; #!/usr/bin/env python # -*- coding: utf-8 -*- #导入smtplib和MIMEText…

多线程的运行状态

多线程运行状态 线程从创建、运行到结束总是处于下面五个状态之一&#xff1a;新建状态、就绪状态、运行状态、阻塞状态及死亡状态。 新建状态 当用new操作符创建一个线程时&#xff0c; 例如new Thread(r)&#xff0c;线程还没有开始运行&#xff0c;此时线程处在新建状态。 当…

LOAD DATA INFILE 语法

原文地址:http://blog.sina.com.cn/s/blog_539f03f00100xfxb.html mysql 的LOAD DATA INFILE 是一个高速insert的不错的方案 篇文章语法介绍的比较详细&#xff0c;转载&#xff0c;记录。 其实我就这样用&#xff1a; load data infile /home/mark/data_update.sql replace i…

@configurationproperties注解的使用_SpringBoot常用注解的简单理解

不定时更新...文章目录Spring容器JavaBeanPOJOAutowiredControllerResourceRestControllerServiceRepositoryMapperComponentEntityTransactionalBeanResponseBodyRestControllerRequestMappingPathVariableRequestParamRequestBody ValueSpringBootApplicationConfigurationPr…

3. Recursive AutoEncoder(递归自动编码器)

1. AutoEncoder介绍 2. Applications of AutoEncoder in NLP 3. Recursive Autoencoder&#xff08;递归自动编码器&#xff09; 4. Stacked AutoEncoder&#xff08;堆栈自动编码器&#xff09; 1. 前言 今天主要介绍用在NLP中比较常见的AutoEncoder的模型&#xff0c;Recursi…

python语言语块句的标记_NLTK基础教程学习笔记(十一)

语块分解例子&#xff1a; from nltk.chunk.regexp import * import nltk test_sent"The prime minister announced he had asked the chief government whip, Philip Ruddock, to call a special party room meeting for 9am on Monday to consider the spill motion.&qu…

Excel的VBA连接数据库方法

Sub GetData() Dim strConn As String, strSQL As String Dim conn As ADODB.Connection Dim ds As ADODB.Recordset Dim col As Integer 清空电子表格的所有数据 Cells.Clear 连接数据库的字符串 strConn "ProviderSQLOLEDB.1;Persist Security InfoTrue;User IDnam…

Python基础4

本节内容 列表、元组操作字符串操作字典操作集合操作文件操作字符编码与转码 1. 列表、元组操作 列表是我们最以后最常用的数据类型之一&#xff0c;通过列表可以对数据实现最方便的存储、修改等操作 定义列表 1names [Alex,"Tenglan",Eric]通过下标访问列表中的元素…

Catalan数(卡特兰数)

公式&#xff1a; n < 2 时&#xff0c; f(n) n; n > 2时&#xff0c; f(n) (4n - 2) / (n1) * f(n-1) 1-100的卡特兰数列表如下&#xff1a; n f(n) 1 1 2 2 3 5 4 14 5 42 6 132 7 429 8 1430 9 …

linux unix域socket_Socket通信原理

对TCP/IP、UDP、Socket编程这些词你不会很陌生吧&#xff1f;随着网络技术的发展&#xff0c;这些词充斥着我们的耳朵。那么我想问&#xff1a;1. 什么是TCP/IP、UDP&#xff1f;2. Socket在哪里呢&#xff1f;3. Socket是什么呢&#xff1f;4. …

LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

>LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 问题说明&#xff1a;当安装VS2012之后&#xff0c;原来的.NET 4.0会被替换为.NET 4.5。卸载VS2012时&#xff0c;不会恢复.NET 4.0。 l 当VS2012安装后&#xff0c;VS2010的cvtres.exe就无法使用了。…

NPOI打印设置

打印设置主要包括方向设置、缩放、纸张设置、页边距等。NPOI 1.2支持大部分打印属性&#xff0c;能够让你轻松满足客户的打印需要。 方向设置首先是方向设置&#xff0c;Excel支持两种页面方向&#xff0c;即纵向和横向。 在NPOI中如何设置呢&#xff1f;你可以通过HSSFSheet.P…

HDOJ 1030 Delta-wave

题目&#xff1a;Problem DescriptionA triangle field is numbered with successive integers in the way shown on the picture below. The traveller needs to go from the cell with number M to the cell with number N. The traveller is able to enter the cell through…

工厂模式个人案例_工厂设计模式案例研究

工厂模式个人案例我有一份工作来检查我们的项目代码质量。 如果我在项目中发现任何障碍&#xff0c;必须将其报告给我的团队负责人。 我发现了很多漏洞&#xff0c;我认为可以在博客上进行讨论。 不是嘲笑作者&#xff0c;而是一起学习和改进自己。 像这段代码一样&#xff0c;…

用Matlab实现字符串分割(split)

我们在这里借助正则表达式函数regexp的split模式。一般语法&#xff1a; S regexp(str, char, split) 其中str是待分割的字符串&#xff0c;char是作为分隔符的字符&#xff08;可以使用正则表达式&#xff09;。分割出的结果存在S中。 以下面这样一串字符为例 Hello N…