2010-12-16 10 views
0

Ich habe erfahren, dass die I. Methode langsamer ist als II. Meine Anwendung macht Echtzeit-Bildverarbeitung. Ich weiß, dass C# für diesen Zweck nicht ideal ist, aber ich kann die leistungskritischen Dinge trennen und es zum Beispiel in C++ machen. Ich frage mich, warum in C# eine einfache Bitmap-Zeichnung ohne Berechnung langsamer ist. Meine Frage: Gibt es schnellere Methoden in C# als ich?C# Picturebox Zeichnungsgeschwindigkeit

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); 
} 

Antwort

4

Das PixelFormat des Bildes ist kritisch. Die überwiegende Mehrheit der Maschinen läuft heute ihren Videoadapter im 32bpp-Modus. Das macht das Format32bppPArgb mehr als 10 mal schneller als alle anderen, einschließlich 32bppArgb und 24bppRgb. Stellen Sie sicher, dass Sie das Bild in diesem Format erstellen und bei Bedarf konvertieren.

Auch sehr wichtig ist, dass Sie das Bild mit seiner Originalgröße zeichnen. Sie tun dies im nativen Code, aber nicht unbedingt mit der PictureBox. Wenn das Bild angepasst werden muss, wird eine qualitativ hochwertige Interpolation auf das Bild angewendet. Das braucht Zeit.

+0

Danke für die Antwort. Mein Code transformiert das Bild nicht (Größenänderung oder Smothing etc.), einfach die Bitmap auf den Bildschirm kopieren. Das Bitmap-Format ist 32bppArgb, da dies der Standardwert ist. – bsebi

+1

PictureBox tut das, was dein Snippet sagt. Der Punkt war, das Bitmap-Format zu * ändern *, verwende nicht den Standard. –

+0

pictureBox1.SizeMode == Normal, also keine Größenanpassung. Jetzt habe ich verschiedene Pixelformate ausprobiert, aber es gab keinen großen Unterschied. – bsebi

2

Ich bin nicht wirklich sicher, was Sie fragen. Warum ist das Zeichnen mit C# langsamer als das Zeichnen mit C++? Vor allem, weil die Standardklasse Graphics, die von .NET Framework bereitgestellt wird, GDI + -Zeichnungsmethoden verwendet, die wesentlich langsamer sind als die von C/C++ verwendeten GDI-Funktionen.

Sie fragen sich, wie Sie beschleunigen in C# zeichnen? Es wäre sehr hilfreich, wenn Sie die relevanten Abschnitte Ihres Codes veröffentlichen würden, die Sie als zu langsam empfinden. Während die Verwendung der Graphics-Bibliothek ist definitiv langsamer als einige der Alternativen, in der Mehrzahl der Fälle, ist die Leistung kein Faktor. Wenn Sie nicht viele Grafiken in einer engen Schleife zeichnen, sollten keine Probleme auftreten. Wenn Sie es sind, ist es wahrscheinlicher, dass Ihr Code optimiert, anstatt vollständig ersetzt werden kann. (Natürlich ist C# nicht das, was Sie verwenden möchten, wenn Sie tatsächlich Echtzeitgrafiken suchen. Es gibt nicht genug Details in Ihrer Frage zu erzählen.)

Alternativ können Sie P/Invoke die GDI -basierte Zeichenfunktionen aus der Win32-API und/oder die Verwendung von unsafe Code in Ihrer C# -Anwendung, um Bitmaps direkt zu bearbeiten. Das sollte Ihnen eine sehr vergleichbare Leistung zu dem Zeichencode in der C++ - DLL geben, die Sie in Ihrer Frage erwähnen, da Sie dieselben Routinen verwenden würden. Sie müssen jedoch noch einmal mehr Details zu Ihrer Frage angeben, wenn jemand von uns spezifischere und hilfreichere Ratschläge geben soll.

+0

Danke für die Antwort, ich habe meine Frage geändert. – bsebi

0

PictureBox macht ein bisschen mehr Hintergrundzeug als nur ein Bild zu zeichnen.

Versuchen Sie, direkt auf ein Steuerelement/Fenster im Paint-Ereignis zu zeichnen.

Graphics.DrawImageUnscaled (...) wird wahrscheinlich die schnellste Framework-Methode sein.

Wenn Sie schneller wollen, dann müssen Sie DirectX oder OpenGL betrachten und die Zeichnung auf dedizierte Hardware laden.

+0

Ich habe DrawImageUnscaled und OpenGL (OpenTK) versucht. Immer noch ist der OpenCV-Code der Beste. Mein Problem damit ist das Einbetten von OpenCV-Fenstern (Bugs). – bsebi