Die Bestimmung der Größe eines JPEG - (JFIF) image
Ich muss die Größe eines JPEG - (JFIF) image. Das Bild wird nicht gespeichert, als stand-alone-Datei, so kann ich nicht verwenden GetFileSize
oder jeder anderen API wie diese hier (das Bild wird in einem stream und keine anderen header vorhanden ist, außer den üblichen JPEG/JFIF-header(s)).
Ich Tat etwas Forschung und fand heraus, dass JPEG-Bilder aus verschiedenen teilen, jeder Teil, beginnend mit einem frame marker (0xFF 0xXX
), und die Größe dieses Rahmens. Mit Hilfe dieser Informationen war ich in der Lage zu analysieren eine Vielzahl von Informationen aus der Datei.
Das problem ist, ich kann nicht finden die Größe der komprimierten Daten, so wie es scheint, gibt es kein frame marker für die komprimierten Daten. Auch scheint es, dass die komprimierten Daten folgt die SOS (FFDA
) Markierung und das Bild endet mit der End Of Image (EOI) (FFD9
) marker.
Einen Weg, dies zu erreichen wäre, um die Suche für die EOI-marker von byte zu byte, aber ich denke, die komprimierte Daten enthalten könnte diese Kombination von bytes, richtig?
Gibt es eine einfache und richtige Weise zu finden, die Gesamtgröße des Bildes? (Ich würde lieber ein paar code/Idee ohne jegliche externe Bibliothek)
Im Grunde, ich brauche den Abstand (in bytes) zwischen dem Start-Image (SOI-FFE0
) und End of Image (EOI-FFD9
).
- Hmm... SOS-marker in der JFIF-Datei?.. Ich habe das Gefühl etwas verpasst in den specs...
- Original-Beitrag sagte: "es ist keine Datei". Er sagt, dass es ist ein SOS und ein EOI. Irgendwie hat er eine JFIF-stream eingebettet, ohne irgendwelche äußeren Wrapper.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die komprimierten Daten umfassen nicht SOI oder EOI bytes, so sind Sie dort sicher. Aber mit der Bemerkung, Anwendung, Daten oder andere Header könnte. Zum Glück, Sie identifizieren können, und überspringen Sie diese Abschnitte als die Länge gegeben ist.
Die JPEG-Spezifikation, die Ihnen sagt, was Sie brauchen:
http://www.w3.org/Graphics/JPEG/itu-t81.pdf
Blick auf Tabelle B. 1 auf Seite 32. Die Symbole, die * nicht haben eine Länge Feld Folgen (RST, SOI, EOI, TEM). Der andere tun.
Müssen Sie überspringen die verschiedenen Felder, aber es ist nicht allzu schlecht.
Wie durch zu gehen:
Lesen beginnen SOI (
FFD8
). Dies ist der start. Es sollte das erste, was in den Bach.Dann, Fortschritt durch die Datei, weitere Marker und das überspringen über dem Header:
SOI-marker (
FFD8
): Beschädigte Bild. Sie sollten gefunden haben, die eine EOI schon!TEM (
FF01
): standalone-marker, weiterzumachen.RST (
FFD0
durchFFD7
): standalone-marker, weiter. Sie konnte bestätigen, dass der Neustart Marker zählen vonFFD0
durchFFD7
und wiederholen, aber das ist nicht notwendig für die Messung der Länge.EOI-marker (
FFD9
): fertig!Jeder marker, der nicht ZUERST ein SOI, EOI, TEM (
FF01
durchFFFE
abzüglich der Ausnahmen oben): Nach der Markierung, Lesen Sie die nächsten 2 bytes, das ist die 16-bit-big-endian-Länge des frame-header (nicht einschließlich des 2-byte-marker, sondern unter anderem auch das Feld "Länge"). Überspringen Sie den angegebenen Betrag (in der Regel der Länge minus 2, da Sie schon diese bytes).Wenn du eine Ende-der-Datei vor EOI, dann hast du ein beschädigtes Bild.
Sobald Sie haben eine EOI, die Sie bekommen haben durch das JPEG-und sollte die Länge. Können Sie erneut starten, indem Sie eine andere Lesen SOI, wenn Sie erwarten, mehr als ein JPEG in Ihrem stream.
FFDA
sowieso.Da Sie keine Sprache geschrieben, ich bin mir nicht sicher, dass dies funktionieren wird, aber:
Können Sie
Stream.Seek(0, StreamOffset.End);
und dann nehmen Sie die stream-position?Bitte spezifisch sein über das, was Rahmen, den Sie verwenden.
Die echte Tatsache der Sache ist, wenn die Datei-header nicht geben Sie die erwartete Größe, die Sie haben zu suchen (oder zu Lesen), um das Ende des Bildes.
BEARBEITEN
Da Sie versuchen, stream mehrere Dateien, die Sie verwenden möchten, werden Sie einen streaming-freundlich-container-format.
OGG sollte eine schöne Passform für diese.
JPEG ist eigentlich schon streaming-freundlich, aber Sie müssen garantieren, dass jede Datei hat ein gültiges Abschlusszeichen, bevor es den Strom hinab oder sonst laufen Sie Gefahr, Absturz Ihrer app mit unerwarteten Eingang.
Vielleicht so etwas wie dieses
In python, Sie konnte nur Lesen die ganze Datei in ein string-Objekt und finden das erste vorkommen von FF E0 und dem letzten auftreten von FF D9. Vermutlich sind dies die start-und Ende, nach dem Sie suchen?