我正在使用Emgu OpenCV从网络摄像头抓取图像,并且想用WPF Image
来控制它们。
所以我需要将图像从Mat
转换为与Image
控件兼容的东西。所以我把从Emgu例子这个类:处理大图像时垃圾收集器速度太慢
public static class BitmapSourceConvert
{
/// <summary>
/// Delete a GDI object
/// </summary>
/// <param name="o">The poniter to the GDI object to be deleted</param>
/// <returns></returns>
[DllImport("gdi32")]
private static extern int DeleteObject(IntPtr o);
/// <summary>
/// Convert an IImage to a WPF BitmapSource. The result can be used in the Set Property of Image.Source
/// </summary>
/// <param name="image">The Emgu CV Image</param>
/// <returns>The equivalent BitmapSource</returns>
public static BitmapSource ToBitmapSource(IImage image)
{
using (System.Drawing.Bitmap source = image.Bitmap)
{
IntPtr ptr = source.GetHbitmap(); //obtain the Hbitmap
BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
ptr,
IntPtr.Zero,
Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
DeleteObject(ptr); //release the HBitmap
return bs;
}
}
}
这就像为小图像(640×480为例)魅力。当使用任务管理器(我在Windows 8上)时,我看到使用的内存在增加和减少。工作正常。
但是,当使用像1920x1080这样的较大图像时,应用程序会在短时间内崩溃,但不会有更多内存。当再次查看任务管理器时,我可以看到内存消耗增加,一旦下降,然后上升,直到抛出异常。 感觉垃圾收集器的工作不足以释放所有空间。
所以我试图通过在函数中的某处添加GC.Collect()手动启动垃圾回收器。它再次运作。即使是大图像。
我认为手动调用垃圾收集器既不是好的样式,也不是高性能的。任何人都可以请提供如何解决这个问题,而无需调用GC.Collect()?
水晶球说,你永远不会调用IImage.Dispose()。是的,GC.Collect()会隐藏这个问题。 –