C#: String als byte schreiben und lesen

Dieses Thema C#: String als byte schreiben und lesen im Forum "C/C++" wurde erstellt von Kababär, 21. Apr. 2016.

Thema: C#: String als byte schreiben und lesen Hi, ich hoffe, dass ihr auch C# erlaubt und nicht aus der Reihe tanzt, weil es weder C noch C++ ist, ich aber...

  1. Hi,

    ich hoffe, dass ihr auch C# erlaubt und nicht aus der Reihe tanzt, weil es weder C noch C++ ist, ich aber hoffe, dass ich trotzdem Hilfe finde (will mich nicht extra in einem C#-Forum anmelden wegen einer Frage..).

    Und zwar geht es um Folgendes:
    Ich will ein Bild einlesen und es in seinen Grauwert transformieren und die Zusammensetzung aller Pixel des gesamten Bildes abspeichern in externes File. Der Inhalt des Files kann nun eingelesen werden und soll wieder in einer pictureBox dargestellt werden.

    Mein Vorgehen:
    Ich lese das Bild ein und konvertiere es in Grau und stelle es dar. Nach dem Klick auf einen Button "Bild speichern" können die Informationen des Bildes auf die Festplatte abgelegt werden.
    Dabei soll in dem File nicht nur die Pixelinformationen des Bildes, sondern auch Höhe und Breite des Bildes enthalten sein. Die Pixelinformationen an sich (also Grauwerte) sollen als Byte abgespeichert werden.
    Mit dieser Methode transformiere ich ein Bild in ein byte-Array.

    Code (Text):
            public byte[] BmpToArray(Bitmap bmp)
            {
                ImageConverter imgCon = new ImageConverter();
                return (byte[])imgCon.ConvertTo(bmp, typeof(byte[]));
            }
    Diesen Code zum Schreiben:
    Code (Text):
    bArr = BmpToArray(grayImage);
                    using (BinaryWriter writer = new BinaryWriter(File.Open(fileName, FileMode.Create)))
                    {
                        writer.Write("Height:" + height);
                        writer.Write("Width: " + width);
                        writer.Close();
                        File.WriteAllBytes(fileName, bArr);
                    }
    Das Schreiben funktioniert einwandfrei. Nur das Lesen bekomme ich nicht hin.
    Ich hatte die Idee das mit File.ReadAllbytes zu machen, aber ich weiß nicht wie ich an den Wert von Height und Width kommen soll und ob pro Pixel ein Byte verwendet wurde oder mehr, oder weniger..
    Könnt ihr mir helfen? :)
     
  2. Vielleicht helfen dir diese Java-Grundlagen weiter --> *Klick*
  3. Sicher dass das "Einwandfrei" funktioniert?
    Mit dem BinaryWriter schreibst du nämlich erst Breite+Höhe in die Datei, schließt den writer und überschreibst dann deine Datei mit dem Bytearray.
    D.h. im Endeffekt stehen nur die Grauwerte in der Datei, ohne deine Breite/Höhe.

    Außerdem würde ich nicht "Height:" + height reinschreiben, sondern direkt nur den Wert für Höhe und Breite.
    Das schreiben kannst du so verändern:
    Code (Text):

    using (BinaryWriter writer = new BinaryWriter(File.Open(fileName, FileMode.Create)))
    {
      writer.Write(height);
      writer.Write(width);
      writer.write(bArr);
    }
     
    Zum lesen eben genau umgekehrt:
    Code (Text):

    using(BinaryReader reader = new BinaryReader(filestream)) {
      width = reader.readInt32();
      height = reader.readInt32();
      data = reader.readBytes(width*height);
    }
     
     
  4. Hey danke für deine Antwort. Dass ich meine Datei überschriebe wusste ich nicht, dachte es Erfolgt ein automatischer Append, wenn ich die Datei vorher nicht lösche.
    Dass das auslesen so einfach ist, hätte ich nicht gedacht. Hab schon damit gerechnet mit Seek, Skip und To zu arbeiten mit der LINQ Version.
    ReadInt32 liest die Höhe wenn diese 40 oder auch 1080 ist oder gar noch größer?

    Mit freundlichen Grüßen
     
  5. Der BinaryWriter/Reader liest/schreibt die Zahlen eben als das was sie sind: 32Bit Ganzzahlen.
    Egal ob du 0, 1, 2, 4000000000 reinschreibst, es werden immer genau 4 Byte geschrieben
     
  6. Danke für die schnelle Antwort :)
    Mit ReadInt16 kann ich analog dazu 2 Bytes einlesen?
     
  7. ja, ReadInt16 liest eben einen short ein (Int16)
     
  8. perfekt danke :)

    Irgendwo habe ich eine LINQ Version gesehen, die so ähnlich aussah:
    Code (Text):
    File(filename).ReadAllBytes().Skip(2).To(10).Seek();
    (Nur beispielhaft)

    Damit könnte ich das obige auch realisieren, richtig?
    Es läuft darauf hinaus, dass ich gewisse Tags eines DICOMs Files später auslesen möchte.
     
    Zuletzt bearbeitet: 22. Apr. 2016
  9. schon, aber damit machst du es nur umständlicher, da du ja die ersten Bytes ja dennoch brauchst.
    Mit der von dir beschriebenen Variante müsstest du das File also zweimal öffnen, einmal für Breite/Höhe und einmal für den Rest. Oder eben hin und her seeken, was es nicht besser macht.

    Daher am besten direkt mit dem BinaryReader direkt in einem Durchlauf alles komplett einlesen
     
  10. Habs hinbekommen, danke :)
     
  11. KOSTENLOSES Java-Grundlagen Training im Wert von 39 € Sichere dir hier den kostenlosen Zugriff auf umfangreiches Java-Know How und starte richtig durch!