Paint Event beschleunigen?
- VB.NET
Sie verwenden einen veralteten Browser (%browser%) mit Sicherheitsschwachstellen und können nicht alle Funktionen dieser Webseite nutzen.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Es gibt 24 Antworten in diesem Thema. Der letzte Beitrag () ist von Fibonacci.
-
-
im New Sub:
SetStyle(OptimizedDoubleBuffer, true) -
-
Der Übersetzer funktioniert grad nicht Richtig, aber hoffentlich hilft dir das trotzdem...
Ich glaube schon, ja. -
-
-
Aber übrigens die Geschwindigkeit der OnPaint-Routine hängt viel häufiger mit anderen Sachen als dem eigentlichen Zeichnen zusammen. Wie z.B mit komplexen Berechnungen innerhalb der Routine, Invalidieren an ungeeigneten Orten etc.
DoubleBuffered unterbindet das zwar meistens, aber bei komplexeren Zeichnungen hast du dann halt immer mehr Perfomance Verlust./nicht getestet -
-
-
-
Ich denke, du solltest wirklich deine Paint-Methode mal zeigen.
Ich zb. male ein bildschirmgroßes Form mit vlt. 50 oder 100 Figuren voll, und das flackert vlt. beim resizen, aber bestimmt keine gefühlte halbe Sekunde.
Mein Prinzip dabei ist, die Figuren in GraphicsPathes vorzubereiten, und die sind dann komplett mit einem Befehl aufs Form gebatscht:
Jdfs. meine ZeichenRoutinen tun wirklich nur zeichnen, einen GraphicsPath nach dem anneren, und das wars auch schon.
Alternativ kann man das neuzeichnen auch aussetzen bis zum Abschluß des Resizing-Vorgangs. Dann gehen die Figuren zwar nicht kontinuirlich mit, aber's klappert nicht so epilepsie-auslösend -
Ok; hier bitte sehr:
VB.NET-Quellcode
- Private Sub Draw_Shape(ByVal Image As PictureBox, ByVal Shape As Shape, ByVal Size As Size, ByVal Color As Color)
- Dim bmp As New Bitmap(Size.Width, Size.Height)
- Dim g As Graphics = Graphics.FromImage(bmp)
- g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
- g.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
- Dim rect As New Rectangle(0, 0, Size.Width, Size.Height)
- Dim lgb As New LinearGradientBrush(rect, Color.FromArgb(100, 100, 100), Color.FromArgb(95, 95, 95), LinearGradientMode.Vertical)
- g.FillRectangle(lgb, rect)
- g.DrawString("blub", New Font("Segoe WP", 32, FontStyle.Regular), Brushes.SeaGreen, New Point(200, 175))
- g.SmoothingMode = Drawing2D.SmoothingMode.None
- g.DrawRectangle(New Pen(New SolidBrush(Color.FromArgb(1000, 100, 100))), New Rectangle(0, 0, Me.Width, Me.Height ))
- If IsMaximized = False Then
- g.SmoothingMode = Drawing2D.SmoothingMode.None
- g.FillRectangle(New SolidBrush(Color), New Rectangle(0, 0, 1, 1))
- g.FillRectangle(New SolidBrush(Color), New Rectangle(0, 1, 1, 1))
- g.FillRectangle(New SolidBrush(Color), New Rectangle(0, 10, 1, 1))
- g.FillRectangle(New SolidBrush(Color), New Rectangle(0, 11, 1, 1))
- g.FillRectangle(New SolidBrush(Color), New Rectangle(0, 100, 1, 1))
- g.FillRectangle(New SolidBrush(Color), New Rectangle(0, 110, 1, 1))
- End If
- Image.BackgroundImage = bmp
- End Sub
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Fibonacci“ ()
-
jo - is doch horror.
da wird in jedem Paint eine Riesen-Bitmap erzeugt, davon ein Graphics gebildet, ins Graphics gemalt, und dann das BackgroundImage der Picbox ausgetauscht.
Statt gleich in die Graphics zu malen, die die PaintEventargs eines PaintEvents dir liefern.
Ausserdem werden 6 SolidBrushes gebildet, mit denen 6 Rechtecke verfüllt werden.
Die könnten alle bereits in einem GraphicsPath angelegt sein, die Rechtecke, und der wäre dann mit einem einzigen Brush und einem einzigen Aufruf hingebatscht.Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()
-
ErfinderDesRades schrieb:
da wird in jedem Paint eine Riesen-Bitmap erzeugt, davon ein Graphics gebildet
... und dieses am Ende nicht mal disposed.
Keine Ahnung, wie oft diese Methode ausgewührt wird. Aber mich interessiert der Speicherverbrauch dieser Anwendung nach einer Stunde Betrieb sehr -
ich hab das mal getestet mit dem massenhaften Erzeugen von Bitmaps, die nicht mehr freigegeben werden:
Sone Anwendung bläst sich gewaltig auf (innerhalb von Sekunden), bis irgendwann nicht mehr weitergeht, und der GarbageCollector quasi einen Befreiungsschlag ausführt.
Merkt man inne Useability erstaunlicherweise kaum, aber sauber ist natürlich was anneres.
@TE: Das müssteste sogar direkt nachgucken können: Starte das Teil mal, und lass dabei den Taskmanager laufen. -
@ErfinderDesRades:
Werde dann mal alles umbasteln. Bin schon auf das Ergebnis gespannt. Danke für die Hilfe! (Und alles Gute zum 1.000sten hilfreichen Post!)
@xtts02:
Whoops; gut, dass du es sagst. Gerade mal angetestet: Im Ruhestand: 20.000 - 25.000 K; nach ein bisschen Laufzeit (mit unzähligen Re-Paints): 170.000 K; Zwischendurch beim Zeichnen: 380.000 K.
Das sollte mir zu denken geben... -
Du kannst auch einen anderen Weg gehen. Dort, wo das Update-Event aufgerufen wird, rufst Du eine Routine zum Erstellen eines neuen Hintergrundbildes auf, die muss nichts mit Paint zu tun haben. So kannst Du mit Paint noch diverse Farbtupfen auf dieses Bild setzen.
Und:
Du musst nicht permanent New SolidBrush(), den kannst Du separat bereitstellen.Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
@xtts02:
Reicht es eigentlich, folgendes zu disposen? Oder noch etwas?
@RodFromGermany:
Ok; habe jetzt erstmal alle SolidBrushes auf eine Variable reduziert. Meinst du, ich solle den Rest in meiner Prozedur so beibehalten? Oder ggf. Teile davon in das Paint Event auslagern? -
Das alles kannsdt Du unabhängig von Paint machen, rufe doch den Code einfach in einer Button_Click auf.Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
ständig neue Bitmaps zu erzeugen ist keine gute Option - wenn die disposed werden, ist das zwar netter zu den System-Resourcen, aber Performance bringt das nicht.
Fibonacci schrieb:
Werde dann mal alles umbasteln. Bin schon auf das Ergebnis gespannt.
mach erstmal ein Gesamt-Backup der Source.
Weil der Umbau ist erheblich.
und schnell mal basteln ist vmtl. auch nicht, weil du musst deine ganze Denke umstellen. Weil bei OwnerDrawing gibts kein Bild mehr, sondern nurnoch Objekte mit Zeichnungs-Informationen.
Und diese Objekte musste selbst programmieren - wenns sauber ablaufen soll, müssen die folgendes können:- jederzeit die aktuellen Abmaße als Rectangle ausgeben. Also nur die Location, wo gemalt wird, reicht nicht
zB eine Methode .GetBounds() As Rectangle - sich jederzeit neu malen können - zB eine Methode DrawObject.Draw(g As Graphics)
Diese Methode kann dann vom PaintEvent für alle DrawObjekte aufgerufen werden. - jederzeit ihren Status ändern
Status kann beinhalten: Position, Drehung, Streckung, und natürlich beliebige Daten, die anzuzeigen sind.
Also um den Status zu ändern machstedann 3 Schritte- me.Invalidate(drawObject.GetBounds()) 'Paint an der alten Position auslösen, dass dort gelöscht wird
- Änderungen am Status
- me.Invalidate(drawObject.GetBounds()) 'Paint an der neuen Position auslösen, dass dort neu gezeichnet wird
- jederzeit die aktuellen Abmaße als Rectangle ausgeben. Also nur die Location, wo gemalt wird, reicht nicht
-
Ähnliche Themen
-
Goldwing Studios - - Sonstige Problemstellungen
-
mit gdi eine linie zeichen die die farbe darunter zu volltranperent ändert
Gelöschter Benutzer - - Sonstige Problemstellungen
-
7 Benutzer haben hier geschrieben
- Gast (11)
- ErfinderDesRades (7)
- ThuCommix (2)
- RodFromGermany (2)
- xtts02 (1)
- rotherford (1)
- jvbsl (1)