Samstag, 30. Oktober 2010

Allgemeiner Fehler in GDI+

Die Fehlermeldung "Allgemeiner Fehler in GDI+." ist ganz schön fies in C# - sie tritt sporadisch auf und die Ursache ist oft auf den ersten Blick nicht ersichtlich. Deswegen werde ich diesen Post der Fehlermeldung und ihren Ursachen widmen und die meiner Meinung nach 2 häufigsten Quellen des Grafikfehlers beschreiben.
Der oben genannte Fehler kann auftreten wenn ein Bild (Image) über die Methode Save() in einen nicht existierenden Pfad gespeichert werden soll.
Folgender Code versucht, den Inhalt der pictureBox als Bild zu speichern und wirft dabei die Fehlermeldung, sofern der angegebene Pfad nicht vorhanden ist:

pictureBox1.Image.Save("C:\\NichtExistierenderPfad\\test.jpg");

Beim Laden eines Bildes führt ein falscher Pfad dagegen zu einer FileNotFoundException.
Eine weitere sehr häufige Ursache des leidigen Fehlers "Allgemeiner Fehler in GDI+." ist die Nichtfreigebung eines Bildobjekts.
Lädt man ein Bild z.B. über die Methode Image.FromFile(), bleibt dieses solange im Speicher geöffet, bis es nicht freigegeben wird. Insbesondere ist vor dem Freigeben kein Speichern über Save() möglich.
Das folgende Codebeispiel lädt ein Bild in die pictureBox und versucht dann, dieses zu speichern - doch es tritt der "Allgemeiner Fehler in GDI+." Fehler auf, da das Bild nicht freigegeben wurde.

pictureBox1.Image = Image.FromFile("C:\\test\\test1.jpg");
pictureBox1.Image.Save("C:\\test\\test2.jpg");

Das Bild muss zur korrekten Funktionsweise des Codes intern "umkopiert" werden:

pictureBox1.Image = Image.FromFile("C:\\test\\test1.jpg");
Image Copy = pictureBox1.Image;
Copy.Save("C:\\test\\test2.jpg");

Ich hoffe, der Post hat die grundlegende Problematik dieses Fehlers deutlich gemacht, über weitere Ursachen, Besonderheiten etc. bin ich jederzeit dankbar!

Kommentare:

  1. Sack und Asche, und das mit als Profi. Merke: Ich bin nie zu erfahren um nicht trotzdem Anfängerfehler zu machen.

    Herzlichen Dank für Dein Blogposting und die darin enthaltenen Tipps!

    PS: Ich hasse GDI+ und die Art der Fehlermeldung trotzdem :-)

    AntwortenLöschen
  2. Der selbe Fehler tritt auch auf, wenn ich das Bild zweimal nacheinander speichere, d.h. die Methode Bild erzeugen, anzeigen, speichern zwei mal aufrufe

    AntwortenLöschen
  3. Ich konnte den Fehler beheben, indem ich die Pfadangabe in der Save()-Methode per "@" escaped habe

    AntwortenLöschen
  4. bis es nicht freigegeben wird,

    gemeint ist sicher, bis es freigegeben wird,
    oder auch: solange es nicht freigegeben ist.

    AntwortenLöschen
  5. Ich hab auch ein Problem mit dem Save
    Bei mir versuche ich eine Bitmap bmp.Save() in ein FileStream zu speichern, anschließend die Bytes oer File.ReadAllBytes in ein ByteArray zu speichern, welches ich dann in einen NetworkStream wegschreibe, den ich per TcpClient erhalte.
    Auf der Gegenseite lese ich dann aus einen NetworkStream, den ich über ein Socket per TcpListener.AcceptSocket()erhalte, zuerst die Größe der Datei aus, erstell ein entsprechendes ByteArray als Buffer, welche ich dann mit ns.Read(buffer, 0, buffer.Length) auslese.
    Diesen Buffer schreibe ich als .bin File weg, um es dann mit einem FileStream zu öffnen und aus dem Stream ein neues Bitmap-Objekt zu erzeugen. Dieses versuche ich dann mit .Save("bild.png", ImageFormat.Png) zu speichern.
    Nur kommt mir hier seltsamer weise ab und zu eine "Allgemeine GDI+" Exception daher. Wenn ich das ganze(Senden und Empfangen) auf ein und dem Selben Rechner oder das Senden per Einzelschritt mach, dann geht es ohne Probleme.

    AntwortenLöschen