Programmabsturz mit Fehler zu wenig Speicher

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

Es gibt 29 Antworten in diesem Thema. Der letzte Beitrag () ist von petaod.

    Programmabsturz mit Fehler zu wenig Speicher

    Moin moin

    Ich habe nochmal an meine Programm weitergearbeitet. Das Programm soll mir einen Text auf ein Bild schreiben, das Bild verkleinern und neu abspeichern.
    Soweit klappt das alles.

    Die original Bilder sind 3000*2000 bei max 1MB! Beim letzten Testlauf waren 120 Bilder gespeichert und hatten alle zusammen eine Größe von 2,8MB!

    Wenn ich das Programm starte läuft das eine Zeitlang ( meist so bis Bild 90 ... 120 ) und dann kommt der Absturz mit dem Fehler: Zu wenig Arbeitsspeicher.
    Siehe Bildanhang.
    Meine Suche bei Tante google usw brachte mich nicht weiter.
    Mein PC hat 16GB RAM

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Sub PutTextonImage()
    2. Directory.CreateDirectory(Sourcepath & "\Fertige")
    3. Dim Files As String() = IO.Directory.GetFiles(Sourcepath, "*.jpg")
    4. Targetpath = Sourcepath & "\Fertige\"
    5. Me.BeginInvoke(Sub() PB_ani.Visible = True)
    6. For Each File As String In Files
    7. Dim ImgName As String = System.IO.Path.GetFileName(File)
    8. Dim newImage As New Bitmap(File)
    9. maxWidth = maxWidth
    10. maxHeight = maxHeight
    11. Dim ratioX = CDbl(maxWidth) / newImage.Width
    12. Dim ratioY = CDbl(maxHeight) / newImage.Height
    13. Dim ratio = Math.Min(ratioX, ratioY)
    14. Dim Width = CInt((newImage.Width * ratio))
    15. Dim Height = CInt((newImage.Height * ratio))
    16. Dim smalImage As New Bitmap(Width, Height)
    17. Using g As Graphics = Graphics.FromImage(smalImage)
    18. g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
    19. g.DrawImage(newImage, New Rectangle(0, 0, Width, Height), New Rectangle(0, 0, newImage.Width, newImage.Height), GraphicsUnit.Pixel)
    20. Dim newText As Graphics = Graphics.FromImage(smalImage)
    21. Using drawBrush As SolidBrush = New SolidBrush(newColor)
    22. Using drawFont As Font = New Font("Segoe UI", newSize)
    23. newsignature()
    24. Dim drawString As String = signature
    25. Dim txtlaenge As SizeF = newText.MeasureString(drawString, drawFont)
    26. Textpos(smalImage.Width, smalImage.Height, CInt(txtlaenge.Width))
    27. newText.DrawString(drawString, drawFont, drawBrush, txtpos_x, txtpos_y)
    28. End Using
    29. End Using
    30. End Using
    31. Dim newFile As String
    32. newFile = Targetpath & ImgName
    33. Threading.Thread.Sleep(100)
    34. Me.BeginInvoke(Sub() lstB_newpic.Items.Add(newFile))
    35. Me.BeginInvoke(Sub() lbl_datei.Text = "Verarbeite Datei: " & newFile)
    36. smalImage.Save(newFile, System.Drawing.Imaging.ImageFormat.Jpeg)
    37. Next
    38. Me.BeginInvoke(Sub() PB_ani.Visible = False)
    39. End Sub

    Bilder
    • fehler1.jpg

      609,52 kB, 1.113×843, 106 mal angesehen
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    den Brush und den Font erstellst Dui in der Klasse genau ein Mal und zeerstörst sie beim Schließen des Programms.

    VB.NET-Quellcode

    1. Graphics = Graphics.FromImage(smalImage)
    kommt zwei Mal vor!!!
    newText brauchsat Du nicht, nimm g und feddich.
    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!
    @petaod
    ​Geh den Umweg über einen Stream
    Da muss ich mich erstmal später einlesen. Aber Danke.
    -------------------------------------------------------------------
    @RodFromGermany und @Bluespide
    Ich dachte immer wenn man "Using / End Using" nutz muss man nicht Disposen? hmmmmm
    Habe nun einiges geändert und mehrere Testläufe mit über 200 Bildern gemacht. Bisher liefe alles ohne Fehler durch.
    Jetzt die Frage: geht noch etwas zu verbessern ohne alles komplett anders zu coden?
    Danke erstmal.

    Hier nun der Update Code:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. #Region "Text & Resize"
    2. Private Async Sub paintimg()
    3. Btn_Bilderladen.Enabled = False
    4. Btn_Bilderspeichern.Enabled = False
    5. LstBox_NewPictures.Items.Clear()
    6. Await Threading.Tasks.Task.Run(Sub() PutTextonImage())
    7. Btn_Bilderladen.Enabled = True
    8. Lbl_Meldungen.Text = "Aktion abgeschlossen, Bilder wurden signiert."
    9. LstBox_OrigPictures.Items.Clear()
    10. End Sub
    11. Public Sub PutTextonImage()
    12. Dim drawBrush As SolidBrush = New SolidBrush(newColor)
    13. Dim drawFont As Font = New Font("Segoe UI", newSize)
    14. Directory.CreateDirectory(Sourcepath & "\SignierteBilder")
    15. Dim Files As String() = IO.Directory.GetFiles(Sourcepath, "*.jpg")
    16. Targetpath = Sourcepath & "\SignierteBilder\"
    17. Me.BeginInvoke(Sub() Pbc_Progress.Visible = True)
    18. For Each File As String In Files
    19. Dim ImgName As String = System.IO.Path.GetFileName(File)
    20. Dim newImage As New Bitmap(File)
    21. maxWidth = maxWidth
    22. maxHeight = maxHeight
    23. Dim ratioX = CDbl(maxWidth) / newImage.Width
    24. Dim ratioY = CDbl(maxHeight) / newImage.Height
    25. Dim ratio = Math.Min(ratioX, ratioY)
    26. Dim Width = CInt((newImage.Width * ratio))
    27. Dim Height = CInt((newImage.Height * ratio))
    28. Dim smalImage As New Bitmap(Width, Height)
    29. Using g As Graphics = Graphics.FromImage(smalImage)
    30. g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
    31. g.DrawImage(newImage, New Rectangle(0, 0, Width, Height), New Rectangle(0, 0, newImage.Width, newImage.Height), GraphicsUnit.Pixel)
    32. newsignature()
    33. Dim drawString As String = signature
    34. Dim txtlaenge As SizeF = g.MeasureString(drawString, drawFont)
    35. Textpos(smalImage.Width, smalImage.Height, CInt(txtlaenge.Width))
    36. g.DrawString(drawString, drawFont, drawBrush, txtpos_x, txtpos_y)
    37. g.Dispose()
    38. End Using
    39. Dim newFile As String
    40. newFile = Targetpath & ImgName
    41. Threading.Thread.Sleep(80)
    42. Me.BeginInvoke(Sub() LstBox_NewPictures.Items.Add(newFile))
    43. Me.BeginInvoke(Sub() LstBox_NewPictures.SelectedIndex = LstBox_NewPictures.Items.Count - 1)
    44. Me.BeginInvoke(Sub() Lbl_Meldungen.Text = "Verarbeite Bild-Nr.: " & newFile)
    45. smalImage.Save(newFile, System.Drawing.Imaging.ImageFormat.Jpeg)
    46. newImage.Dispose()
    47. Next
    48. Me.BeginInvoke(Sub() Pbc_Progress.Visible = False)
    49. drawBrush.Dispose()
    50. drawFont.Dispose()
    51. End Sub
    52. #End Region

    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Amelie schrieb:

    Ich dachte immer wenn man "Using / End Using" nutz muss man nicht Disposen?
    Völlig korrekt. Using räumt auf.
    g.Dispose() kannst Du weglassen und newImage in ein Using packen.
    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!
    @Amelie Wenn Du Post #4 eingearbeitet hast, sollte Dein Problem vollständig gelöst sein.
    Zeile 20 in Deinem Code: Dim newText As Graphics = Graphics.FromImage(smalImage) hat jedes Mal ein Bild alloziiert und nicht freigegeben.
    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!
    @Panter
    Alles gut, da läut nur der eine Prozess ;)
    @RodFromGermany
    So läuft ja nun alles ohne Absturz.
    ​hat jedes Mal ein Bild alloziiert und nicht freigegeben. <=== Verstehe nicht ganz.
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    @Amelie Suche das Vorkommen von newText in DXeinem Code oben, es wird nicht disposed.

    VB.NET-Quellcode

    1. Dim newText As Graphics = Graphics.FromImage(smalImage)
    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!
    @ErfinderDesRades
    Doch war schon drin ;)
    --------------------------------

    Hab nochmal überarbeitet. Kann nun auch auswählen welchen Typ ( jpg / png etc.. ) ich nutzen kann.
    Soweit klappt das nun.

    Eine Frage: Wie ist das mit diesem neuen Bildformat: web/webm?
    Geht das auch schon mit VB?

    Habe dazu so vieles unterschiedliches gelesen...
    ----------------------------

    Hier nun der geänderte Code:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. #Region "Text & Resize & Converting"
    2. Private Async Sub PaintImage()
    3. Btn_Bilderladen.Enabled = False
    4. Btn_Bilderspeichern.Enabled = False
    5. LstBox_NewPictures.Items.Clear()
    6. Await Threading.Tasks.Task.Run(Sub() PutTextonImage())
    7. Btn_Bilderladen.Enabled = True
    8. Lbl_Meldungen.Text = "Aktion abgeschlossen, Bilder wurden signiert."
    9. LstBox_OrigPictures.Items.Clear()
    10. End Sub
    11. Public Sub PutTextonImage()
    12. Dim drawBrush As SolidBrush = New SolidBrush(newColor)
    13. Dim drawFont As Font = New Font("Segoe UI", newSize)
    14. Directory.CreateDirectory(Sourcepath & "\SignierteBilder")
    15. Dim Files As String() = IO.Directory.GetFiles(Sourcepath, "*." & SourceExtension)
    16. Targetpath = Sourcepath & "\SignierteBilder\"
    17. Me.BeginInvoke(Sub() Pbox_Progress.Visible = True)
    18. For Each File As String In Files
    19. Dim ImgName As String = IO.Path.GetFileNameWithoutExtension(File)
    20. Dim newImage As New Bitmap(File)
    21. maxWidth = maxWidth
    22. maxHeight = maxHeight
    23. Dim ratioX = CDbl(maxWidth) / newImage.Width
    24. Dim ratioY = CDbl(maxHeight) / newImage.Height
    25. Dim ratio = Math.Min(ratioX, ratioY)
    26. Dim Width = CInt((newImage.Width * ratio))
    27. Dim Height = CInt((newImage.Height * ratio))
    28. Dim smalImage As New Bitmap(Width, Height)
    29. Using g As Graphics = Graphics.FromImage(smalImage)
    30. g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
    31. g.DrawImage(newImage, New Rectangle(0, 0, Width, Height), New Rectangle(0, 0, newImage.Width, newImage.Height), GraphicsUnit.Pixel)
    32. CheckSignature()
    33. Dim drawString As String = signature
    34. Dim txtlaenge As SizeF = g.MeasureString(drawString, drawFont)
    35. Textpos(smalImage.Width, smalImage.Height, CInt(txtlaenge.Width))
    36. g.DrawString(drawString, drawFont, drawBrush, txtpos_x, txtpos_y)
    37. End Using
    38. Dim newFile As String
    39. newFile = Targetpath & ImgName & "." & TargetExtension
    40. Threading.Thread.Sleep(30)
    41. Me.BeginInvoke(Sub() LstBox_NewPictures.Items.Add(newFile))
    42. Me.BeginInvoke(Sub() LstBox_NewPictures.SelectedIndex = LstBox_NewPictures.Items.Count - 1)
    43. Me.BeginInvoke(Sub() Lbl_Meldungen.Text = "Verarbeite Bild-Nr.: " & newFile)
    44. smalImage.Save(newFile, ImgFormat)
    45. newImage.Dispose()
    46. Next
    47. Me.BeginInvoke(Sub() Pbox_Progress.Visible = False)
    48. drawBrush.Dispose()
    49. drawFont.Dispose()
    50. End Sub
    51. #End Region

    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Ja das meinte ich diese neue Google-Format.
    Leider kann ich mit dem aus den links noch nichts anfangen..
    Ich dachte es gäbe da etwas einfacheres... ;(
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Amelie schrieb:

    Doch war schon drin
    EDR meint: Ist nicht disposed worden.
    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!
    Hi

    Für Bildformate wie webp, heic, heiv und andere einfach ein paar WIC (Windows Imaging Component)-APIs (oder wer möchte auch WIC-COM-Interfaces) verwenden. Da brauch man keine zusätzlichen Verweise oder Fremdpakete. Voraussetzung ist allerdings das auch entsprechende WIC-Codecs installiert sind bzw bringt WIC bereits ein paar eingebaute Codecs mit. webm lassen sich zb per MediaFoundation wiedergeben.
    Mfg -Franky-

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