2010-12-16 36 views
0

我經歷過I方法比II慢。我的應用程序進行實時圖像處理。我知道C#對於這個目的並不理想,但我可以將性能關鍵的東西分開,並以C++爲例。我想知道爲什麼在C#中慢一個簡單的位圖繪圖沒有任何計算。我的問題是:在C#中有更快的方法,然後我?C#繪圖箱繪圖速度

I. C#: 

void DrawImg(Bitmap b) 
{ 
    pictureBox1.Image = b; 
    pictureBox1.Invalidate(); 
} 

II. C# + C++ + OpenCV 

C# side: 
[DllImport("MyWrapper.dll")] 
static extern void showimg(IntPtr p, int x, int y); 

void DrawImg(Bitmap b) 
{ 
     BitmapData d = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); 
     showimg(d.Scan0, d.Width, d.Height); 
     b.UnlockBits(d); 
} 

C++ side: 
extern "C" void __stdcall showimg(uchar* p, int x, int y) 
{ 
    Mat img; // OpenCV's Mat class 
    img.create(y, x, CV_8UC3); 
    img.data = p; 
    imshow("Window1", img); 
} 

回答

4

圖像的PixelFormat非常關鍵。今天絕大多數機器都以32bpp模式運行他們的視頻適配器。這使得Format32bppPArgb比其他任何其他版本快10倍以上,包括32bppArgb和24bppRgb。請確保以該格式創建圖像,並在必要時進行轉換。

同樣非常重要的是,您可以用原始尺寸繪製圖像。你在本地代碼中這樣做,但不一定在PictureBox中。如果需要調整圖像大小,它會在圖像上使用高質量插值。這需要時間。

+0

感謝您的回覆。我的代碼不會轉換圖片(調整大小或打掃等),只需將位圖複製到屏幕即可。位圖的格式是32bppArgb,因爲這是默認值。 – bsebi 2010-12-16 20:39:16

+1

PictureBox確實如此,這就是你的代碼片斷說你使用。重點是*改變*位圖格式,不要使用默認值。 – 2010-12-16 20:41:51

+0

pictureBox1.SizeMode ==正常,所以沒有調整大小。現在我嘗試了不同的像素格式,但沒有太大的區別。 – bsebi 2010-12-16 22:36:06

2

我不確定你在問什麼。爲什麼用C#繪圖比用C++繪製要慢?主要是因爲.NET Framework提供的標準Graphics類使用GDI +繪圖方法,這比C/C++使用的GDI函數要慢得多。

你想知道如何在加速在C#中繪圖?如果您發佈代碼中相關的部分(如果您感覺速度太慢),這將非常有幫助。在大多數情況下,使用Graphics庫肯定比一些替代方法慢,但它的性能不是一個因素。除非你在緊密循環中繪製大量圖形,否則不應該遇到任何問題。如果你是,那麼你的代碼更可能是優化,而不是完全取代。 (當然,如果你真的在尋求實時圖形,C#並不是你想要使用的東西,你的問題中沒有足夠的細節來說明)。

或者,你可以P /調用GDI基於Win32 API的繪圖函數和/或考慮在您的C#應用​​程序中使用unsafe代碼來直接操作位圖。這應該會提供與您在問題中提到的C++ DLL中的繪圖代碼非常相似的性能,因爲您將使用相同的例程。但是,如果我們任何人提供更具體,有用的建議,您需要再次提供有關您問題的更多詳細信息。

+0

感謝您的回覆,我修改了我的問題。 – bsebi 2010-12-16 16:32:15

0

PictureBox不僅僅是繪製圖像,它的背景更多。

嘗試在繪畫事件中直接繪製到控件/窗口上。

Graphics.DrawImageUnscaled(...)可能會是最快的框架方法。

如果您想要更快,那麼您需要查看DirectX或OpenGL並將繪圖卸載到專用硬件。

+0

我試過DrawImageUnscaled和OpenGL(OpenTK)。 OpenCV代碼仍然是最好的。我的問題很難嵌入OpenCV的窗口(bug)。 – bsebi 2010-12-21 12:56:57