【问题标题】:C# fast pixel renderingC# 快速像素渲染
【发布时间】:2012-06-17 08:16:48
【问题描述】:

我正在使用 OpenNI 开发深度处理(Xbox Kinect、Asus Xtion 等)应用程序。

当传感器提供新的深度数据(30 或 60 fps 取决于分辨率)时,我需要一种非常简单且快速的方式在 Windows 窗体上绘图。

目前,当数据可用时,我正在从单独的线程中使双缓冲面板无效,然后在面板的绘制方法中设置位图的像素,从而产生可预见的糟糕的 5fps。

System.Drawing.Graphics 似乎缺乏设置单个像素的快速方法,除非任何人另有指示。

我实际上只需要设置像素颜色,因此希望尽可能避免使用第三方高速渲染 API,最好使用尽可能原生的东西。

有人有什么建议吗?

【问题讨论】:

  • 您目前如何设置像素?
  • 使用 image.SetPixel(x, y, colour) 创建了一个位图。毕竟,调用 graphics.drawImage(image, etc)
  • SetPixel 非常慢。看看Scanline 方法。

标签: c# graphics drawing rendering kinect


【解决方案1】:

如果您使用的是位图,那么您应该使用 LockBits 和 UnlockBits 直接访问内存中的数据。在 C# 中,您可以通过使用不安全的代码块和指针来获得一些额外的性能。

查看此链接了解更多信息:http://web.archive.org/web/20150227183132/http://bobpowell.net/lockingbits.aspx

【讨论】:

  • 这是一个巨大的改进。绘制空白 640x480 位图时,我无法达到超过 10 fps,因此结论是 System.Drawing 从根本上说并不快。该解决方案结合缩小图像并仅渲染部分像素以实现所需的 FPS 就是答案。
【解决方案2】:

image.SetPixel() 在每帧替换很多像素并且每秒需要很多帧时非常慢。

使用WriteableBitmap 并调用CopyPixels 会快很多

通过这种方式,您可以使用多个线程将像素数据填充到数组中,并在一次调用中简单地将数组blit 到图像中。

编辑

请注意,WriteableBitmap 是一个 WPF 类。如果您绑定到 WinForms,您可能需要创建自己的实现。 WPF/WinForms/GDI interop: converting a WriteableBitmap to a System.Drawing.Image?

【讨论】:

  • 感谢您的回复,但是您提供的答案链接在从 WriteableBitmap 到 System.Drawing.Image 的转换中使用了 .SetPixel()。
  • 是的,这对速度来说太可怕了。另一种方法是写入数组并使用编码器(PNG,BMP,...)将其转换为图像并显示它。 SetPixel 的主要问题是它设置了单个像素。
【解决方案3】:

您可以尝试我的LINQ image processing library 来处理您的“缓冲区位图”。它使用非常易于访问的语法,但对于大型位图非常高效。它可以在 Nuget 上以单个文件的形式包含在您的项目中。

希望有帮助!

【讨论】:

    猜你喜欢
    • 2012-08-01
    • 1970-01-01
    • 2010-09-13
    • 2010-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多