Zeichnen im .Paint Event wesentlich beschleunigen

    • VB.NET
    • .NET (FX) 4.5–4.8

    Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von dive26.

      Zeichnen im .Paint Event wesentlich beschleunigen

      Hallo Leute,

      ich habe viele Anwendungen wo ich direkt im Paint-Event (von z.B. einem Panel oder Button) zusätzliche grafische Ausgaben mache.
      Bisher eben immer im Paint-Event mit e.graphics.

      Da ich jetzt an einem neuen Projekt arbeite und dieses sehr grafiklastige Ausgaben auf Panels macht, ist das direkte Zeichnen im .Paint Event zu langsam.
      Zeichne ich aber alles in eine Bitmap und kopiere diese dann in das Panel.BackgroundImage, dann habe ich eine bis zu 200 Mal schnellere Ausgabe.

      Hier ein Beispielcode:

      VB.NET-Quellcode

      1. 'Deklaration einer Bitmap
      2. Public ZeichenFlaeche As Bitmap
      3. Public Sub Zeichne(PNL As Panel)
      4. PNL.BackgroundImage = Nothing
      5. If ZeichenFlaeche IsNot Nothing Then ZeichenFlaeche.Dispose()
      6. ZeichenFlaeche = New Bitmap(PNL.Width, PNL.Height)
      7. Using g As Graphics = Graphics.FromImage(ZeichenFlaeche)
      8. g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
      9. g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
      10. g.Clear(Color.Black)
      11. 'hier weitere Ausgaben mit g.DrawLine, g.DrawString etc. ausführen
      12. End Using
      13. 'Gezeichnete Bitmap auf das Panel zurückschreiben
      14. PNL.BackgroundImage = ZeichenFlaeche
      15. End Sub
      Bilder
      • Reports.jpg

        351,53 kB, 1.280×720, 63 mal angesehen
      • BOPV.uno.jpg

        355,66 kB, 1.280×720, 61 mal angesehen
      Liebe Grüße
      Roland Berghöfer

      Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „dive26“ ()

      Ich kann das nicht bestätigen.
      Es liegt hier auch eine Ereigniskette vor.
      Weil das Zuweisen eines BackgroundImages löst ein Paint-Event aus, und wenn im Paint-Event wieder ein BackgroundImage zugewiesen wird geht das immer im Kreis.
      Und zwar so schnell irgend möglich.
      Das ist also tatsächlich maximal schnell, aber um den Preis einer 100%igen Auslastung eines Processor-Kernels (zumindest bei mir).

      In anhängiger Sample-App habe ich ein konventionelles Drawing gebaut, und darin eine gleiche Ereigniskette angerichtet:

      VB.NET-Quellcode

      1. Private Sub _Canvas_Paint(sender As Object, e As PaintEventArgs)
      2. If ckBackgroundBitmap.Checked Then Zeichne(Canvas) Else Draw(e.Graphics) : Canvas.Invalidate()
      3. End Sub
      Wie man sieht kann man das Zeichnen umschalten von Dive26s' Zeichne() auf mein Draw(), und bei Draw ist der verkettende Aufruf extra hinzugeschrieben.

      Im Vergleich zeigt sich: Die konventionelle Zeichnung rennt doch noch ca. 50% schneller im Kreis als die Lösung mit dem BackgroundImage.

      Aber schön ist beides nicht: eine Anwendung sollte nicht dauerhaft derart Cpu-Last verursachen.

      Es bleibt also bei der altbekannten Unerfreulichkeit: WinForms ist für grossflächige Animationen nicht ausgelegt.
      Bilder
      • 2023-10-11 22_50_34-DrawingPerform.png

        143,38 kB, 1.083×767, 41 mal angesehen
      Dateien
      @ErfinderDesRades
      Das hast Du falsch verstanden. Ich rufe in der Paint-Routine überhaupt keinen Code auf. Das Paint-Event ist leer.
      Der Zeichenprozess wird extern gestartet. CPU-Last ist bei mir nicht messbar.
      Liebe Grüße
      Roland Berghöfer

      Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at