# C#: String als byte schreiben und lesen



## Kababär (21. Apr 2016)

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.


```
public byte[] BmpToArray(Bitmap bmp)
        {
            ImageConverter imgCon = new ImageConverter();
            return (byte[])imgCon.ConvertTo(bmp, typeof(byte[]));
        }
```

Diesen Code zum Schreiben:

```
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?


----------



## InfectedBytes (22. Apr 2016)

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:

```
using (BinaryWriter writer = new BinaryWriter(File.Open(fileName, FileMode.Create)))
{
  writer.Write(height);
  writer.Write(width);
  writer.write(bArr);
}
```

Zum lesen eben genau umgekehrt:

```
using(BinaryReader reader = new BinaryReader(filestream)) {
  width = reader.readInt32();
  height = reader.readInt32();
  data = reader.readBytes(width*height);
}
```


----------



## Kababär (22. Apr 2016)

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


----------



## InfectedBytes (22. Apr 2016)

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


----------



## Kababär (22. Apr 2016)

Danke für die schnelle Antwort  
Mit ReadInt16 kann ich analog dazu 2 Bytes einlesen?


----------



## InfectedBytes (22. Apr 2016)

ja, ReadInt16 liest eben einen short ein (Int16)


----------



## Kababär (22. Apr 2016)

perfekt danke 

Irgendwo habe ich eine LINQ Version gesehen, die so ähnlich aussah:

```
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.


----------



## InfectedBytes (22. Apr 2016)

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


----------



## Kababär (22. Apr 2016)

Habs hinbekommen, danke


----------

