2012-06-14 153 views
7

我正在开发使用OpenNI的深度处理(Xbox Kinect,Asus Xtion等)应用程序。C#快速像素渲染

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

当数据变得可用时,我从一个单独的线程中使双缓冲面板失效,然后在面板的paint方法中设置一个位图像素,产生可预测的可怕5fps。

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

我从字面上只需要设置像素颜色,所以如果可能的话,要避免使用第三方高速渲染API,理想情况下尽可能使用本机。

有没有人有任何建议?

+0

你现在怎么设置像素? – leppie

+0

使用image.SetPixel(x,y,color)创建位图。毕竟,调用graphics.drawImage(图像等) –

+2

'SetPixel'非常缓慢。看看'Scanline'方法。 – leppie

回答

4

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

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

+0

这是一个巨大的改进。绘制空白640x480位图时,我无法达到10fps以上,因此得出的结论是System.Drawing从根本上说不是很快。这个解决方案结合缩放图像并仅渲染一些像素来实现所需的FPS就是答案。 –

4

image.SetPixel()当您每帧替换许多像素并且您需要每秒很多帧时速度非常慢。

这将是快了很多,当你使用一个WriteableBitmap,并呼吁CopyPixels

这样你就可以使用多线程填充像素数据的阵列和简单的blit阵列的图像在一个单一的电话。

编辑

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

+0

感谢您的回复,但您提供的答案链接在从WriteableBitmap到System.Drawing.Image的转换中使用.SetPixel()。 –

+0

是的,这对速度来说太可怕了。另一种方法是写入数组并使用编码器(PNG,BMP,...)将其转换为图像并显示。 SetPixel的主要问题是它设置了一个像素。 –

0

你可以试试我LINQ image processing library与您的“缓冲位图”的工作。它使用非常容易理解的语法,但对于大型位图非常有效。它可在Nuget上作为单个文件包含在您的项目中。

希望有帮助!