2016-05-27 11 views
-1

Ich habe eine Stream myStream und ich möchte ein JPEG davon bekommen. Das wäre in Ordnung, wenn der Stream nur ein JPEG wäre, würde ich einfach tun Image img = Image.FromStream(MyStream); aber der Stream ist eigentlich eine Kopfzeile (ASCII-Text), gefolgt von einem JPEG, gefolgt von einer Kopfzeile, gefolgt von einem JPEG ...Wie bekomme ich mehrere Bilder aus einem Filestream in C#

I kann die Header leicht extrahieren, und sie enthalten Informationen über das JPEG (insbesondere seine Auflösung und Größe in Bytes), aber ich weiß nicht, wie ich dann die Bilder bekomme und sie auf der Festplatte speichern kann (eigentlich will ich nur anzeigen) sie nacheinander in einer Animation, aber es ist ein bisschen die gleiche Sache).

Wer irgendwelche Ideen?

Hier ist, was der Strom wie folgt aussieht:

[320,240,10734]jpegDataIncomprihensibleTextGoingOnForAges[320,240,10032]jpegDataIncomprihensibleTextGoingOnForAges...

+0

Wenn Sie Header extrahieren kann, was verhindert, dass Sie Bilder in gleicher Weise zu extrahieren? Sie kennen ihre Größe. – Evk

+0

Haben Sie versucht, den Wert "Größe in Bytes" zu verwenden, um zu ermitteln, wie viele Bytes aus dem Stream für das aktuelle Bild gelesen werden sollen? Machen Sie das dann als Schleife, bis keine Daten mehr vorhanden sind. – Tom

+0

weil ich sie durch das Lesen extrahiere, bis ich komme] aber ich weiß nicht, was das jpeg mit –

Antwort

3

Zuerst Sie wirklich nicht wollen, dies versuchen, mit einer Textdatei zu tun. Sie möchten die Datei als Binär lesen, und das ist, was BinaryReader ist.

Also lesen Sie die erste Überschrift. Das gibt Ihnen die JPEG-Größe in Bytes. Positioniere die Datei an den Anfang des JPEGs und lese so viele Bytes in den Speicher. Dann erstellen Sie eine MemoryStream und konstruieren Sie das Bild aus diesem Stream.

Also, im Großen und Ganzen:

var reader = new BinaryReader(File.Open(fileName, FileMode.Open)); 
while not end of file 
{ 
    // read header. Probably want to read characters one at a time here. 
    StringBuilder sb = new StringBuilder(); 
    char c; 
    do 
    { 
     c = reader.ReadChar(); 
     sb.Append(c); 
    } while c != ']'; 
    var header = sb.ToString(); 

    // parse header. One of the fields you get is SizeInBytes 

    var imageBytes = reader.ReadBytes(SizeInBytes); 
    var stream = new MemoryStream(imageBytes); 
    var jpeg = Image.FromStream(stream); 

    // do what you want with the jpeg here. 

    // the file should be positioned at the start of the next header 
    // so just do it all again until no more data. 
} 
+0

Das sieht nach der perfekten Antwort aus. memoryStream war der Schlüssel zur Lösung dieses Problems. Danke für Ihre Hilfe. Außerdem denke ich, es ist 'Leser.Lesen (SizeInBytes);' aber ich könnte mich irren. Danke für den Tipp über BinaryReader auch. –

+0

Tut mir leid, Sie haben recht, 'reader.ReadBytes (SizeInBytes);' funktioniert für BinaryReader, was Sie benutzt haben, aber ich bin mir sicher, dass Sie das wissen. Ich werde meine Unwissenheit woanders nehmen –

+0

@captainjamie: Sie könnten auch 'reader.Read (imageBytes, 0, SizeInBytes)' verwenden, vorausgesetzt, Sie haben 'imageBytes' (ein Array von Byte) vor der Zeit zugewiesen. –