2012-06-14 203 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上作爲單個文件包含在您的項目中。

希望有幫助!