GDI+ Datei wird nicht richtig freigeben

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

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    GDI+ Datei wird nicht richtig freigeben

    Guten Morgen,
    Ich hab seit ein gestern ein Problem welches mich zum verzweifeln bringt.
    Und zwar öffnet der Benutzer sein Bild und dann wird nur ein Teil davon angezeigt, so weit so gut. Will er jedoch das Bild bearbeiten (oder bessergesagt wenn mein Programm das Bild überschreiben will), kommt "Allgemeiner Fehler in GDI+". Dadurch das ich das Bild nicht bearbeiten kann würde ich sagen das, dass Programm die Datei nicht richtig frei gibt.
    Im Internet hab ich was mit FileStream gefunden. Würde ich die Datei sofort wieder ausgeben funktioniert es mit FileStream, aber dem ich Klone mach (oder was auch immer der Fehler beginnt) funktioniert das nicht mehr. Zudem hab ich noch wenig erfahrung mit FileStream.

    Derzeiten Quelltext:

    VB.NET-Quellcode

    1. Dim Width_Ende As String = NumericUpDown3.Value * NumericUpDown1.Value + NumericUpDown3.Value
    2. Dim Height_Ende As String = NumericUpDown4.Value * NumericUpDown2.Value + NumericUpDown4.Value
    3. Dim Width_Ende2 As String = NumericUpDown1.Value
    4. Dim Height_Ende2 As String = NumericUpDown2.Value
    5. Dim Width_Start As String = Width_Ende - NumericUpDown1.Value - 1
    6. Dim Height_Start As String = Height_Ende - NumericUpDown1.Value - 1
    7. If CheckBox1.Checked = True Then
    8. Width_Ende2 = NumericUpDown1.Value + 1
    9. Height_Ende2 = NumericUpDown1.Value + 1
    10. End If
    11. Try
    12. Dim fs As System.IO.FileStream
    13. fs = New System.IO.FileStream(Image, IO.FileMode.Open, IO.FileAccess.Read)
    14. Dim myBitmap As New Bitmap(fs)
    15. Dim gr As Graphics = Graphics.FromImage(myBitmap)
    16. Dim cloneRect As New Rectangle(Width_Start, Height_Start, Width_Ende2, Height_Ende2)
    17. Dim format As PixelFormat = myBitmap.PixelFormat
    18. Dim cloneBitmap As Bitmap = myBitmap.Clone(cloneRect, format)
    19. Width_With_GridLine.Text = ""
    20. Height_With_GridLine.Text = ""
    21. If CheckBox1.Checked = True Then
    22. Dim test As Graphics = Graphics.FromImage(cloneBitmap)
    23. Dim LinePunkt1 As New Point(NumericUpDown1.Value, 0)
    24. Dim LinePunkt2 As New Point(NumericUpDown1.Value, NumericUpDown2.Value)
    25. Dim LinePunkt3 As New Point(0, NumericUpDown2.Value)
    26. Dim LinePunkt4 As New Point(NumericUpDown1.Value, NumericUpDown2.Value)
    27. test.DrawLine(Pens.Yellow, LinePunkt1, LinePunkt2)
    28. test.DrawLine(Pens.Yellow, LinePunkt3, LinePunkt4)
    29. Width_With_GridLine.Text = "(" & cloneBitmap.Width & " mit GridLines)"
    30. Height_With_GridLine.Text = "(" & cloneBitmap.Height & " mit GridLines)"
    31. End If
    32. If CheckBox2.Checked = True Then
    33. cloneBitmap.MakeTransparent(Color.Black)
    34. End If
    35. gr.DrawImage(cloneBitmap, 0, 0)
    36. PictureBox1.Image = cloneBitmap
    37. ImageName.Text = Split(TextBox1.Text, "\")(Split(TextBox1.Text, "\").Count - 1) 'Nicht den besten weg (weis ich jetzt auch)
    38. BoxWidthLabel.Text = NumericUpDown1.Value
    39. BoxHeightLabel.Text = NumericUpDown2.Value
    40. RowLabel.Text = NumericUpDown3.Value
    41. ColLabel.Text = NumericUpDown4.Value
    42. ImageNewName.Text = ""
    43. ImageName.Visible = True
    44. 'Jede menge auf True setzten
    45. PictureBox1.Padding = New Padding(PictureBox1.Width / 2 - cloneBitmap.Width / 2, PictureBox1.Height / 2 - cloneBitmap.Height / 2, PictureBox1.Width / 2 - cloneBitmap.Width / 2, PictureBox1.Height / 2 - cloneBitmap.Height / 2)
    46. fs.Close()


    Vielen Dank für euche Zeit!
    Hi noob98,
    also ich habs grad auch ausprobiert, das mit dem filestream (Dim fs as new filestream(...)) bei mir kam auch eine fehlermeldung daher, weil ich die ressourcen nicht frei gegeben habe, versuch mal den filestream, des bitmap und graphics in einem using block zu schreiben

    VB.NET-Quellcode

    1. Using fs As New FileStream(image, IO.FileMode.Open, FileAccess.Read)
    2. Dim myBitmap As New Bitmap(fs)
    3. Dim gr As Graphics = Graphics.FromImage(myBitmap)
    4. PictureBox1.Image = myBitmap
    5. End Using

    hoffe es hilft!
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    //EDIT:
    Vielen dank für die viele Hilfe!
    Ich hab jetzt die UsingBlock beispiel von Radinator.
    Wenn ich aber probiere die Datei zu bearbeiten kommt der selbe fehler. Dispose bringt auch nichts, zudem bekomme ich eine Fehlermeldung wenn ich probiere Pic.Image.Dispose() und/auch wenn ich probiere cloneBitmap.Dispose() zumachen.
    Fehler:

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

    leider nicht...hatte in meinem vs auch ein tesprojekt mit ner picture box und nem button, bei dem ich auf den button geklickt habe und es dann ein bild, dessen pfad ich angeben hab, in die picture box einfügt. wenn ich myBitmap und gr auch dispose, dann wird bei mir seltsamerweise ein weisser hintergrund, rot umrandet mit rotem X angezeigt. wenn ich das mit dem disposen lasse, sehe ich das bild...is iwie doof find ich
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell

    Radinator schrieb:

    ... wenn ich myBitmap und gr auch dispose, dann wird bei mir seltsamerweise ein
    weisser hintergrund, rot umrandet mit rotem X angezeigt. wenn ich das mit dem disposen lasse, sehe ich das bild...is iwie doof find ich

    Naja, wenn du der PictureBox sein Lieblingsbild wegnimmst.. was soll er dann anzeigen? :)

    "Nichts" kann er nicht anzeigen... und das Teilt er dir mit dem Roten Bildchen mit..

    Wann immer du dein rotex X siehst, oder sagen wir ein rot durchkreuztes Bild, dann gabs Ärger. Es wird dir mitgeteilt, das das Control nicht gezeichnet werden kann.
    als "krücke", lade ein "dummybild" in die Picturebox, dann ist auch das Bild welches vorher drinnen war, freigegeben und du kannst getrost löschen (ohne dispose der Picturebox)

    hmm.. also ich habe mein bestes versucht, deinen Code zu übernehmen.
    aber da gibs 1000 Variablen, die nicht deklariert sind, und ich nicht weiss was sie sind :(
    Nach ein paar Minuten Anpassung habe ich es aufgegeben, das ding bei mir am Laufen zu bekommen.

    Reduziere doch mal deinen Code auf das nötigste ( auch wenn er dann nicht mehr genau das macht was er soll), aber ich denke für dieses Beispiel ist es nicht wichtig, das in irgendwelchen TextBoxen die irgendwelche Dinge eingetragen werden müssen.
    Je einfacher es die Leute zum Testen übernehmen können, um so höher die Chance das dir einer hilft (vermute ich mal)
    @noob98 Was sind das für Bilder?
    • Farbtiefe
    • Format
    • Größe
    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!
    Also ich habs nochmal in Angriff genommen und alles entfernt (wo ich dachte .. is unwichtig..)

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Drawing.Imaging
    2. Public Class Form1
    3. Dim image As String = "C:\caspic\100-07-05-41.png"
    4. Private Sub xx()
    5. Dim fs As System.IO.FileStream
    6. fs = New System.IO.FileStream(image, IO.FileMode.Open, IO.FileAccess.Read)
    7. Dim myBitmap As New Bitmap(fs)
    8. Dim gr As Graphics = Graphics.FromImage(myBitmap)
    9. Dim cloneRect As New Rectangle(100, 100, 100, 100)
    10. Dim format As New PixelFormat
    11. Dim cloneBitmap As Bitmap = myBitmap.Clone(cloneRect, format)
    12. gr.DrawImage(cloneBitmap, 0, 0)
    13. PictureBox1.Image = cloneBitmap
    14. PictureBox1.Padding = New Padding(PictureBox1.Width / 2 - cloneBitmap.Width / 2, PictureBox1.Height / 2 - cloneBitmap.Height / 2, PictureBox1.Width / 2 - cloneBitmap.Width / 2, PictureBox1.Height / 2 - cloneBitmap.Height / 2)
    15. fs.Close()
    16. End Sub
    17. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    18. Try
    19. System.IO.File.Delete(image)
    20. Catch ex As Exception
    21. MsgBox("AUA")
    22. End Try
    23. End Sub
    24. Private Sub Form1_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
    25. xx()
    26. End Sub
    27. End Class


    dummerweise löscht er das Bild ohne Mukken, und angezeigt bleibt es in deiner PictureBox.
    .. also freigegeben ist die Datei
    *wunder*

    noob98 schrieb:

    den ihr nicht wissen konntet
    Weil ich immer mein Problem nicht vollständig beschreibe. X(
    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!