【问题标题】:WPF performance: resetting source of Image controlsWPF 性能:重置图像控件的源
【发布时间】:2012-05-29 12:34:19
【问题描述】:

我正在使用 AForge.NET 库定期从我的网络摄像头获取图像数据。出于调试原因,我必须将过滤后的图像绘制到屏幕上。 目前,我的主窗体上有 6 个 WPF 图像,每秒钟我都会处理一个事件,该事件给了我一个 UnmanagedImage,我将其转换为 System.Drawing.Bitmap,然后转换为 BitmapSource - 我的代码如下所示:

private void OnImageFiltered(object sender, FilterEventArgs e)
{
    var bitmapSource = e.UnmanagedImage.ToManagedImage().ToBitmapSource();
    pictureBox.Source = bitmapSource;
}

但正如我之前所说,我有 6 张图片,这会减慢整个程序的速度。 我怎样才能让它更快?

我的 ToBitmapSource 扩展方法在这里:

public static BitmapSource ToBitmapSource(this System.Drawing.Image source)
{
    System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(source);

    var bitSrc = bitmap.ToBitmapSource();

    bitmap.Dispose();
    bitmap = null;

    return bitSrc;
}

【问题讨论】:

  • 我相信bitmap.ToBitmapSource() 是最昂贵的组件,但您可以使用 bool 参数构造函数节省少量开销,如var bitmapSource = e.UnmanagedImage.ToManagedImage(false).ToBitmapSource();。由于它是事件驱动的,它很可能已经在后台线程上发生,对吗?
  • 整个事情(我的意思是事件处理程序代码)在 Dispatcher.Invoke 中,使用 DispatcherPriority.Send,因为它在后台线程上运行。
  • 所以我会对解决此类问题的“最佳实践”感兴趣?例如,在一个 WPF 表单中绘制 6 个网络摄像头?也许我在重置图像源时完全错了......
  • 在后台处理图像不会使程序“更快”,但它会使它看起来更具响应性。尝试在后台线程中获取BitmapSource,然后只通过Dispatcher.Invoke设置pictureBox.Source
  • 但是当我在后台线程上调用 ToBitmapSource 时,我得到一个错误:“调用线程无法访问这个对象*,因为不同的线程拥有它”(*该对象是 BitmapSource 对象,它是在这种情况下是一个 InteropBitmap)

标签: c# .net wpf performance imagesource


【解决方案1】:

很抱歉写了一个答案,但由于我的声誉低,我还不能发表评论。

如果问题仍然存在,请使用 Freeze 方法将 BitmapSource 设置为只读,从而可以传递给不同的线程。

【讨论】:

    猜你喜欢
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-10
    • 1970-01-01
    相关资源
    最近更新 更多