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 = ;
for (int i = ; 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

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 / );
section = CreateFileMapping(new IntPtr(-), IntPtr.Zero, 0x04, , pcount, null);
map = MapViewOfFile(section, 0xF001F, , , pcount);
bitmapSource = Imaging.CreateBitmapSourceFromMemorySection(section, (int)videoSource.Width, (int)videoSource.Height, PixelFormats.Bgr32,
(int)(videoSource.Width * PixelFormats.Bgr32.BitsPerPixel / ), ) 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(, , (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", );
} } 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", );
}
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 Members public 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 / );
section = CreateFileMapping(new IntPtr(-), IntPtr.Zero, 0x04, , pcount, null);
map = MapViewOfFile(section, 0xF001F, , , pcount);
bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromMemorySection(section, (int)this.Width, (int)this.Height, PixelFormats.Bgr32,
(int)(this.Width * PixelFormats.Bgr32.BitsPerPixel / ), ) 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(, , (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 Members public 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图形用户界面相关程序,包含的函数用来绘制图像和显示文字。

												

C# WPF 显示图片和视频显示 EmuguCv、AForge.Net测试的更多相关文章

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

    介绍 本文是接着上文<C# WPF 显示图片和视频显示 EmuguCv.AForge.Net测试>写的,建议先看下上文,因为有些代码还需要了解. 增添 接着上文的代码,我们可以在事件处理方 ...

  2. WPF显示图片

    1.WPF显示图片内部一部分 <Rectangle Height="> <Rectangle.Fill > <ImageBrush ImageSource=&q ...

  3. wpf image控件循环显示图片 以达到动画效果 问题及解决方案

    1>最初方案: 用wpf的image控件循环显示图片,达到动画效果,其实就是在后台代码动态改变Image.Source的值,关键代码: ; i < ; i++)//六百张图片 { Bitm ...

  4. WPF 获取元素(Visual)相对于屏幕设备的缩放比例,可用于清晰显示图片

    原文:WPF 获取元素(Visual)相对于屏幕设备的缩放比例,可用于清晰显示图片 我们知道,在 WPF 中的坐标单位不是屏幕像素单位,所以如果需要知道某个控件的像素尺寸,以便做一些与屏幕像素尺寸相关 ...

  5. C# wpf image绑定viewModel没有显示图片

    在wpf绑定图片,用viewModel的图片绑定image 我是用viewModel.cs public class viewModel:INotifyPropertyChanged { #regio ...

  6. WPF 标签预览可以显示图片运行后不显示

    使用<Image HorizontalAlignment="Left" Height="100" Margin="106,111,0,0&quo ...

  7. EmguCV控件Emgu.CV.UI.ImageBox及C# picturebox显示图片连续刷新出现闪烁问题

    在上一篇里,EmguCV(OpenCV)实现高效显示汉字及叠加  实现了视频叠加及显示,但存在问题,就是 Emgu.CV.UI.ImageBox及C# picturebox显示图片时都会出现闪烁,尤其 ...

  8. wpf显示视频,image控件闪屏,使用winform控件实现

    使用C#调用mingw的动态库实现视频识别软件,程序通过C++调用opencv打开视频,将图像的原始数据以rgb24的方式传递给C#端,C#通过构造图像对象给控件赋值的方式显示图片. 一开始使用wpf ...

  9. WPF 修改图片颜色

    原文:WPF 修改图片颜色 本文告诉大家如何修改图片的颜色,如去掉图片的蓝色 在 WPF 可以使用很多图片处理的方法,本文告诉大家的是一个图片处理,可以把处理的图片保存在文件. 在阅读本文,我假设大家 ...

随机推荐

  1. mysqli事务处理demo

    <?php  $mysqli=new mysqli("localhost", "root", "123456", "xsph ...

  2. [Usaco2010 OPen]Triangle Counting 数三角形

    [Usaco2010 OPen]Triangle Counting 数三角形 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 394  Solved: 1 ...

  3. Microsoft Visual Studio 下载转帖

    1.VS2010 2.VS2012 Visual Studio 2012 Ultimate旗舰版序列号: YKCW6-BPFPF-BT8C9-7DCTH-QXGWC YQ7PR-QTHDM-HCBCV ...

  4. html的解析

    Web页面运行在各种各样的浏览器当中,浏览器载入.渲染页面的速度直接影响着用户体验 简单地说,页面渲染就是浏览器将html代码根据CSS定义的规则显示在浏览器窗口中的这个过程.先来大致了解一下浏览器都 ...

  5. [Elixir008]Nested Module里的动态函数调用方式

    有时我们需要动态生成一些模块名,然后调用它里面的函数.但是我们常常碰到的却是明明有那个模块,结果还是raise模块未定义... 我们来看看到底怎么回事? 首先我们定义一个函数 iex(1)> d ...

  6. c++ 标准库的各种容器(vector,deque,map,set,unordered_map,unordered_set,list)的性能考虑

    转自:http://blog.csdn.net/truexf/article/details/17303263 一.vector vector采用一段连续的内存来存储其元素,向vector添加元素的时 ...

  7. no2.crossdomain.xml批量读取(待完善)

    读取太多url有问题 #coding=utf-8 import urllib import requests import sys import re import time def getxml(u ...

  8. IOS开发之——Masonry 只支持OC,暂不支持swift

    前言 1 MagicNumber -> autoresizingMask -> autolayout 以上是纯手写代码所经历的关于页面布局的三个时期 在iphone1-iphone3gs时 ...

  9. 定制类自己的的new_handler

    C++中的new操作符首先使用operator new函数来分配空间,然后再在此空间上调用类的构造函数构造对象.当operator new无法分配所需的内存空间时,默认的情况下会抛出一个bad_all ...

  10. JS的十大经典算法排序

    引子 有句话怎么说来着: 雷锋推倒雷峰塔,Java implements JavaScript. 当年,想凭借抱Java大腿火一把而不惜把自己名字给改了的JavaScript(原名LiveScript ...