PictureBox verbraucht viel Arbeitsspeicher

  • VB.NET
  • .NET (FX) 1.0–2.0

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von 112marv.

    PictureBox verbraucht viel Arbeitsspeicher

    Hallo,
    ich habe mir ein Programm geschrieben, welches ein Bild in einer Picturebox anzeigt, sobald es in zu einem überwachenden Ordner hinzugefügt wird.
    Das funktioniert alles wunderbar. Was mir nun leider aufgefallen ist, dass mit jedem Bild, das neu angezeigt wird, der Bedarf an Arbeitsspeicher steigt.
    Nun habe ich schon versucht nach dem Laden des Bildes mit "PictureBox.Image.Dispose" oder "Bitmap.Dispose" den Speicher wieder zu leeren, leider ohne Erfolg.

    Hat jemand eine Idee?
    Vielen Dank.
    Klar. Sry.

    Visual Basic-Quellcode

    1. 'Function AutoSizeImage skaliert das Bild
    2. Public Function AutoSizeImage(ByVal oBitmap As Image, _
    3. ByVal maxWidth As Integer, _
    4. ByVal maxHeight As Integer, _
    5. Optional ByVal bStretch As Boolean = False) As Image
    6. ' Größenverhältnis der max. Dimension
    7. Dim maxRatio As Single = CSng(maxWidth / maxHeight)
    8. ' Bildgröße und aktuelles Größenverhältnis
    9. Dim imgWidth As Integer = oBitmap.Width
    10. Dim imgHeight As Integer = oBitmap.Height
    11. Dim imgRatio As Single = CSng(imgWidth / imgHeight)
    12. ' Bild anpassen?
    13. If (imgWidth > maxWidth Or imgHeight > maxHeight) Or (bStretch) Then
    14. If imgRatio <= maxRatio Then
    15. ' Größenverhältnis des Bildes ist kleiner als die
    16. ' maximale Größe, in der das Bild angezeigt werden kann.
    17. ' In diesem Fall muss die Bildbreite angepasst werden.
    18. imgWidth = CInt(imgWidth / (imgHeight / maxHeight))
    19. imgHeight = maxHeight
    20. Else
    21. ' Größenverhältnis des Bildes ist größer als die
    22. ' maximale Größe, in der das Bild angezeigt werden kann.
    23. ' In diesem Fall muss die Bildhöhe angepasst werden.
    24. imgHeight = CInt(imgHeight / (imgWidth / maxWidth))
    25. imgWidth = maxWidth
    26. End If
    27. ' Bitmap-Objekt in der neuen Größe erstellen
    28. Dim oImage As New Bitmap(imgWidth, imgHeight)
    29. ' Bild interpolieren, damit die Qualität erhalten bleibt
    30. Using g As Graphics = Graphics.FromImage(oImage)
    31. g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
    32. g.DrawImage(oBitmap, New Rectangle(0, 0, imgWidth, imgHeight))
    33. End Using
    34. ' neues Bitmap zurückgeben
    35. Return oImage
    36. Else
    37. ' unverändertes Originalbild zurückgeben
    38. Return oBitmap
    39. End If
    40. End Function
    41. Private Sub FileSystemWatcher1_Created(ByVal sender As System.Object, ByVal e As System.IO.FileSystemEventArgs) Handles FileSystemWatcher1.Created
    42. 'Kurze Wartezeit, da sonst das Bild nicht geladen wird.
    43. Thread.Sleep(200)
    44. 'Bild laden (aus Function AutoSizeImage)
    45. 'Der Pfad kommt vom FileSystemwatcher
    46. Dim oStream As New System.IO.FileStream(FileSystemWatcher1.Path + "\" + e.Name.ToString, IO.FileMode.Open)
    47. Dim oBitmap As Bitmap
    48. oBitmap = New Bitmap(oStream)
    49. oStream.Close()
    50. ' Bild soll optimal an die Größe der PictureBox angepasst und angezeigt werden
    51. With thumbnail.PictureBox1
    52. .Image = AutoSizeImage(oBitmap, .ClientRectangle.Width, .ClientRectangle.Height)
    53. End With
    54. With fullscreen.PictureBox1
    55. .Image = AutoSizeImage(oBitmap, .ClientRectangle.Width, .ClientRectangle.Height)
    56. End With
    57. 'Bild um 180° drehen
    58. If thumbnail.CheckBox1.Checked = True Then
    59. Dim bild As Image
    60. bild = thumbnail.PictureBox1.Image
    61. bild.RotateFlip(RotateFlipType.Rotate180FlipNone)
    62. thumbnail.PictureBox1.Image = bild
    63. Threading.Thread.Sleep(100)
    64. thumbnail.PictureBox1.Refresh()
    65. bild = fullscreen.PictureBox1.Image
    66. bild.RotateFlip(RotateFlipType.Rotate180FlipNone)
    67. fullscreen.PictureBox1.Image = bild
    68. Threading.Thread.Sleep(100)
    69. fullscreen.PictureBox1.Refresh()
    70. End If
    71. End Sub
    Wenn dein Bitmap skaliert wird, und ein neues zurückgegeben wird, gibst du das alte nicht frei. Wenn die AutoSizeImage-Methode nirgendwo anders genutzt wird, solltest du vor Zeile 41 ​oBitmap.Dispose() aufrufen.
    Mit freundlichen Grüßen,
    Thunderbolt
    @ Thunderbolt: Habe oBitmap.Dispose() nun in Zeile 39 eingefügt. Sobald das erste Bild geladen wird schließt sich das Programm mit folgender Fehlermeldung.

    @ ErfinderDesRades: Das funktioniert aber leider auch nicht so, wie ich es mir gedacht habe. Die Bilder werden eigentlich alle verzehrt, egal was ich einstelle.
    Bilder
    • Unbenannt-1.jpg

      18,32 kB, 452×390, 114 mal angesehen

    RodFromGermany schrieb:

    Zurückgezogen, war inzwischen alles da.

    Aber ich glaube das funktioniert. Zumindest steigt der Arbeitsspeicherbedarf jetzt nicht mehr stark an.

    ErfinderDesRades schrieb:

    hmm - bei mir nicht. SizeMode.Zoom bewirkt die zentrierte Darstellung ohne jede Verzerrung, und Sizemode.StretchImage stretcht halt so, dass die gesamte Picturebox-Oberfläche bemalt ist.

    Stimmt hast recht. Keine Ahnung warum es neulich nicht funktioniert hat. Mit Zoom gehts. Aber löst die Problematik leider nicht und das Bild drehen funktioniert so auch nicht mehr.

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