Allgemeiner Fehler in GDI+ und wie man ihn fixt

    • C#
    • .NET (FX) 4.5–4.8

      Allgemeiner Fehler in GDI+ und wie man ihn fixt

      Hi Leute,

      wollte nur hier nur eine kurze Information mit Euch teilen. Hierbei geht es darum, eine Bitmap aus einem Stream zu laden und sie anschließend zu speichern.

      Des öfteren kommt es dabei zu einer mehr oder weniger(eher mehr ;D) kryptischen Fehlermeldung: Allgmeiner Fehler in GDI+
      Da einem diese Meldung nicht wirklich viel sagt, kann man sich eigentlich nur notgedrungen bei Google auf die Suche begeben und halt irgendwie sein Problem mehr oder weniger genau zu beschreiben und hoffen, dass ein Posting auf die eigene Fehlerbschreibung passt.
      Hier auch in meinem Beispiel.

      Kurz als Hintergrundstory, wie ich auf das Problem gestoßen bin:
      ich wollte eine Png Datei zur Probe(zum testen) per TCP Verbindung mit NetworkStream als byte-Array von PC zu PC schicken.
      Sender

      C#-Quellcode

      1. using System.IO;
      2. using System.Net;
      3. using System.Text;
      4. using System.Drawing;
      5. using System.Net.Sockets;
      6. using System.Drawing.Imaging;
      7. namespace AppSender
      8. {
      9. class Program
      10. {
      11. public const string BinaryFileName = "file.bin";
      12. static void Main(string[] args)
      13. {
      14. Bitmap bmp = new Bitmap("C:\\img.png");
      15. bool b = File.Exists(BinaryFileName);
      16. if (b)
      17. {
      18. File.Delete(BinaryFileName);
      19. }
      20. using (FileStream fs = new FileStream(BinaryFileName, FileMode.CreateNew))
      21. {
      22. bmp.Save(fs, ImageFormat.Png);
      23. }
      24. var data = File.ReadAllBytes(BinaryFileName);
      25. TcpClient client = new TcpClient();
      26. IPAddress clientIp = IPAddress.Parse("192.168.178.47");
      27. client.Connect(clientIp, 4444);
      28. using (NetworkStream ns = client.GetStream())
      29. {
      30. byte[] byteData = Encoding.Default.GetBytes(data.Length.ToString());
      31. ns.WriteByte((byte)byteData.Length);
      32. ns.Write(byteData, 0, byteData.Length);
      33. ns.Write(data, 0, data.Length);
      34. }
      35. }
      36. }
      37. }
      Als Ausgangssituation hab ich Sender und Empfänger App auf dem selben Rechner laufen lassen. Das hat dann auch geklappt. Nur als ich das ganze dann auf 2 PCs verteilen wollte, kam ständig auf dem Empfänger Rechner beim wieder aufbauen(Das byte-Array als binary File wegschreiben und mit FileStream auslesen und mit dem Stream eine neue Bitmap erzeugen) und anschließendem Speichern die besagte Allgemeiner GDI+ Exception.
      Empfänger

      C#-Quellcode

      1. using System;
      2. using System.IO;
      3. using System.Net;
      4. using System.Linq;
      5. using System.Text;
      6. using System.Drawing;
      7. using System.Net.Sockets;
      8. using System.Drawing.Imaging;
      9. namespace AppEmpfaenger
      10. {
      11. class Program
      12. {
      13. public const string BinaryFileName = "file.bin";
      14. public const string PngFileName = "bild.png";
      15. static void Main(string[] args)
      16. {
      17. if (File.Exists(BinaryFileName))
      18. File.Delete(BinaryFileName);
      19. if (File.Exists(PngFileName))
      20. File.Delete(PngFileName);
      21. IPAddress myIP = Dns.GetHostAddresses(Environment.MachineName).ToList().Find((x) => x.AddressFamily == AddressFamily.InterNetwork);
      22. TcpListener client = new TcpListener(myIP, 4444);
      23. Bitmap bmp;
      24. client.Start();
      25. Socket socket = client.AcceptSocket();
      26. using (NetworkStream ns = new NetworkStream(socket))
      27. {
      28. byte[] sizebuffer = new byte[ns.ReadByte()];
      29. ns.Read(sizebuffer, 0, sizebuffer.Length);
      30. byte[] data = new byte[int.Parse(Encoding.Default.GetString(sizebuffer))];
      31. ns.Read(data, 0, data.Length);
      32. File.WriteAllBytes(BinaryFileName, data);
      33. using (FileStream fs = new FileStream(BinaryFileName, FileMode.Open, FileAccess.Read))
      34. {
      35. bmp = new Bitmap(fs);
      36. bmp.save(PngFileName, ImageFormat.Png);
      37. }
      38. }
      39. }
      40. }
      41. }
      Hab das ganze Problem dann auch über mehrer Tage hinweg beobachten können.Nur wenn das Senden im Singel-Step machte, dann hats geklappt.

      Dann bin ich eher per Zufall auf einen Post auf stackoverflow.com gestoßen, in dem jemand ein ähnliches Problem schilderte. Jedenfalls war die Erklärung, warum das Save() Probleme verursachte ist so einfach wie auch dämlich: Das Laden aus dem Stream sperrt die Bitmap. Einfach lässt sich das ganze lösen, indem man sich eine Copy-Bitmap erstellt, die man schließlich speichert.
      Empfänger

      C#-Quellcode

      1. //...
      2. File.WriteAllBytes(BinaryFileName, data);
      3. using (FileStream fs = new FileStream(BinaryFileName, FileMode.Open, FileAccess.Read))
      4. {
      5. bmp = new Bitmap(fs);
      6. Bitmap copy = new Bitmap(bmp);
      7. copy.Save(PngFileName, ImageFormat.Png);
      8. }
      9. //...


      Das ganze ist jetz nur ein Beispiel (mir ist auch klar, dass man die Bitmap nicht erst als Binary File speichern, auslesen, die bytes per Networkstream versenden und umgehehrt wieder aufbauen, sondern auch einfach in einen Stream Speichern, dank Save()-Überladung) Hier geht es nur um die Problematik, dass eine aus einem Stream geladene Bitmap nicht einfach per Save als Datei gespeichert werden soll. Dabei ist es (leider) egal, ob der Stream ein NetworkStream oder MemoryStream oder ein BinaryStream ist.
      t
      Ich hoffe ich konnte wem helfen ;D

      Lg Radinator
      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