![]() |
Bildgröße von Bilddateien
Wie kann man die Bildgröße (Breite und Höhe) von jpg, jpeg, gif und png Dateien ermitteln?
|
Re: Bildgröße von Bilddateien
Zitat:
.tiff und .ico nicht vergessen. |
@Daniel B: "Schlafmütze" :mrgreen:, sieht das Thema, antwortet und merkt nicht dass es in der falschen Sparte steht und verschieb es dann logischer weise auch nicht. :roll:
|
Zitat:
|
Das ist im allgemeinen anders für jeden Typ. Bei
![]() Delphi kann JPEG laden - macht es leichter. Torry bietet Komponenten für GIF - laden und ebenfalls auslesen. Für andere Grafikformate hilft nur die oben genannte Webseite. |
@TPercon:
Also, bei jpg-bildern kannst du's ja über'n verstecktes image-feld mit autosize:=true auslesen. und wegen den gif-pics: schau mal auf ![]() greetz, -movax- | ![]() |
Habe mir von wotsit.org Infos runtergeladen und versuche seit 3 Tagen da vorwärts zu kommen. Schaffe aber noch nichtmal einen richtigen Ansatz fürs Auslesen der Bildinfos für ein Format zu finden, da die Codebeispiele sich z.B. beim jpeg über mehrere Units erstrecken und somit etwas durcheinander herrscht. Kennt jemand vielleicht nen brauchbaren Ansatz für irgendeins der obigen Formate ohne ne extra Komponente zu benutzen.
|
ich sag doch: bei jpeg kannst du's über ne unsichtbare image-box machen, einfach die unit jpeg einbinden (ist bei delphi dabei), dann klappt's auch mit den jpegs ;)
|
Das möchte ich ja gerade nicht. Ich möchte die Bildgröße aus den markern auslesen und keine Komponente oder zusätzliche Unit verwenden.
|
Hi,
also GIF ist recht einfach. Infos von ![]()
Code:
Die GIF Signatur ist immer folgender Aufbau:
+-----------------------+
| +-------------------+ | | | GIF Signature | | | +-------------------+ | | +-------------------+ | | | Screen Descriptor | | | +-------------------+ | | +-------------------+ | | | Global Color Map | | | +-------------------+ | . . . . . . | +-------------------+ | ---+ | | Image Descriptor | | | | +-------------------+ | | | +-------------------+ | | | | Local Color Map | | |- Repeated 1 to n times | +-------------------+ | | | +-------------------+ | | | | Raster Data | | | | +-------------------+ | ---+ . . . . . . |- GIF Terminator -| +-----------------------+ GIF87a, also drei Bytes für "GIF" und drei für die Version. Anschließend kommt der "Screen Discriptor"
Code:
Da stehen sofort Breite und Höhe des Bildes. Kurz, die Bytes 6 und 7 (0-basiert zählend) speichern die Breite, die Bytes 8 und 9 die Höhe. Wenn Du diese einfach mittles AssignFile, und Read ausließt, dann hasst Du die Ausmaße des GIF Bildes. Für JPEGs würde ich Dir dringend empfehlend diese in ein TBitmap zu laden (Keine Komponente!) und Dir die Werte für Breite und Höhe zurückgeben zu lassen, da es bei diesem Typ ungleich schwerer wird. Bedenke, JPEG können auch im Video-Stream Format (JFIF) kommen.
7 6 5 4 3 2 1 0 Byte
# +---------------+ | | 1 +-Screen Width -+ Raster width in pixels (LSB first) | | 2 +---------------+ | | 3 +-Screen Height-+ Raster height in pixels (LSB first) | | 4 +-+-----+-+-----+ M = 1, Global color map follows Descriptor |M| cr |0|pixel| 5 cr+1 = # bits of color resolution +-+-----+-+-----+ pixel+1 = # bits/pixel in image | background | 6 background=Color index of screen background +---------------+ (color is defined from the Global color |0 0 0 0 0 0 0 0| 7 map or default map if none specified) +---------------+ :cat: |
also dann.. ich hab mich mal hingesetzt und schnell was für dich zusammengeschustert:
Code:
so, jetzt hast du in den Variablen Width und Height die Breite und die Höhe des GIF-Bilds (sofern es ein GIF89-konformes GIF ist ;))
[b]procedure[/b] TForm1.Button1Click(Sender: TObject);
[b]var[/b] gif: integer; dmy: [b]array[/b][0..3] [b]of[/b] Char; Width, Height: integer; [b]begin[/b] gif := FileOpen('blabla.gif'); FileSeek(gif, 6, 0); [color=#000080][i]//<- man könnte hier noch testen, ob // davor der GIF-Tag in der Datei // steht..[/i][/color] FileRead(Gif,dmy,4); FileCLose(gif); Width := ord(dmy[1]) * 256 + ord(dmy[0]); [color=#000080][i]//<- die hex-werte umwandeln[/i][/color] Height := ord(dmy[3]) * 256 + ord(dmy[2]); [b]end[/b]; Ich hoffe, das hilft dir weiter.. Der Code prüft übrigens nicht, ob's sich bei der datei wirklich um ein GIF handelt, dazu brauchst du aber nur testen, ob die ersten 3 bzw. 5 bytes 'GIF' bzw. 'GIF89' sind ;) greetz, -movax- | ![]() |
@movax: Ich bin mir sicher: Tpercon wirds danken. :)
:cat: |
Danke sakura für die Erklärung! Und natürlich auch an movax ein Danke.
Dann werde ich fürs jpeg wohl nicht drum rum kommen, die Unit jpeg (macht das Prog ca. 90 kB größer :( ) mit einzubinden. Hat jemand sonst zu den anderen Formaten (.png) ne Idee oder so ne gute Erklärung? |
Hi
Die Breiten und Höhenangabe steht beim Icon beim 6. und 7. Byte, beim png vom 16.- 19. und 20. - 23. Byte. Beim jpeg muß da doch auch irgend ne Regelmäßigkeit sein?! |
Eine Regelmäßigkeit gibts schon, aber die hat ein paar verschiedene Abhängigkeiten...
Code:
Das heisst, Du musst zuerst das Segment finden, welches mit dem Marker 0xFFC0 markiert ist, und das muss nicht das erste Segment sein, da dort auch andere Informationen gespeichert sein können. in diesem Segment musst Du Byte 5 und 6 für die Höhe lesen und Byte 7 und 8 für die Breite.
JPEG/JFIF file format:
~~~~~~~~~~~~~~~~~~~~~~ - header (2 bytes): $ff, $d8 (SOI) (these two identify a JPEG/JFIF file) - for JFIF files, an APP0 segment is immediately following the SOI marker, see below - any number of "segments" (similar to IFF chunks), see below - trailer (2 bytes): $ff, $d9 (EOI) Segment format: ~~~~~~~~~~~~~~~ - header (4 bytes): $ff identifies segment n type of segment (one byte) sh, sl size of the segment, including these two bytes, but not including the $ff and the type byte. Note, not Intel order: high byte first, low byte last! - contents of the segment, max. 65533 bytes. Notes: - There are parameterless segments (denoted with a '*' below) that DON'T have a size specification (and no contents), just $ff and the type byte. - Any number of $ff bytes between segments is legal and must be skipped. Segment types: ~~~~~~~~~~~~~~ *TEM = $01 usually causes a decoding error, may be ignored SOF0 = $c0 Start Of Frame (baseline JPEG), for details see below SOF1 = $c1 dito SOF2 = $c2 usually unsupported SOF3 = $c3 usually unsupported SOF5 = $c5 usually unsupported SOF6 = $c6 usually unsupported SOF7 = $c7 usually unsupported SOF9 = $c9 for arithmetic coding, usually unsupported SOF10 = $ca usually unsupported SOF11 = $cb usually unsupported SOF13 = $cd usually unsupported SOF14 = $ce usually unsupported SOF14 = $ce usually unsupported SOF15 = $cf usually unsupported DHT = $c4 Define Huffman Table, for details see below JPG = $c8 undefined/reserved (causes decoding error) DAC = $cc Define Arithmetic Table, usually unsupported *RST0 = $d0 RSTn are used for resync, may be ignored *RST1 = $d1 *RST2 = $d2 *RST3 = $d3 *RST4 = $d4 *RST5 = $d5 *RST6 = $d6 *RST7 = $d7 SOI = $d8 Start Of Image EOI = $d9 End Of Image SOS = $da Start Of Scan, for details see below DQT = $db Define Quantization Table, for details see below DNL = $dc usually unsupported, ignore SOI = $d8 Start Of Image EOI = $d9 End Of Image SOS = $da Start Of Scan, for details see below DQT = $db Define Quantization Table, for details see below DNL = $dc usually unsupported, ignore DRI = $dd Define Restart Interval, for details see below DHP = $de ignore (skip) EXP = $df ignore (skip) APP0 = $e0 JFIF APP0 segment marker, for details see below APP15 = $ef ignore JPG0 = $f0 ignore (skip) JPG13 = $fd ignore (skip) COM = $fe Comment, for details see below All other segment types are reserved and should be ignored (skipped). SOF0: Start Of Frame 0: ~~~~~~~~~~~~~~~~~~~~~~~ - $ff, $c0 (SOF0) - length (high byte, low byte), 8+components*3 - data precision (1 byte) in bits/sample, usually 8 (12 and 16 not supported by most software) - image height (2 bytes, Hi-Lo), must be >0 if DNL not supported - image width (2 bytes, Hi-Lo), must be >0 if DNL not supported - number of components (1 byte), usually 1 = grey scaled, 3 = color YCbCr or YIQ, 4 = color CMYK) - for each component: 3 bytes - component id (1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q) - sampling factors (bit 0-3 vert., 4-7 hor.) - quantization table number
Code:
:cat:
NOTE: The JPEG/JFIF file format uses Motorola format for words, NOT Intel format,
i.e. : high byte first, low byte last -- (ex: the word FFA0 will be written in the JPEG file in the order : FF at the low offset , A0 at the higher offset) |
Hi
Kann das sein, dass jpeg Dateien FFC2 haben und jpg FFC0? So ist das nämlich bei den Dateien bei mir!? Wenn das immer so wäre, dann kann ich die jetzt auch erfolgreich auslesen. Gruß |
Eigentlich sollte es nicht so sein, aber wer weiss... Am besten erst nach 0xFFC0 suchen, und wenn es dieses nicht gibt nach 0xFFC2... Theoretisch kommt JPEG daher, dass seit Win95 die Dateiendung nicht mehr auf 3 Zeichen begrenzt ist und seit dem auch UNIX Dateinamen funktionieren...
|
Habt ihr den jpeg Dateien wo das nicht C2 ist?
|
Moin Tpercon,
also auf Dateiendungen würde ich mich prinzipiell nicht verlassen. Zur exakten Feststellung des Dateityps sind i.d.R. die Headerinformationen in Dateien die diese bieten gedacht. |
Prinzipiell hast du natürlich recht!
Die ersten 10 Byte's sind bei beiden gleich. Mich würde es halt trotzdem interessieren. |
Kurz: ja, ich speichere meine JPG files oft mit JPEG
:cat: |
Wie unterscheide ich die denn jetzt voneinander?
Am Anfang steht bei beiden FF D8. Am 21. Byte habe ich beim jpg nen DB und beim jpeg nen EC nach dem FF. Kann ich danach gehen? Oder soll ich doch am Besten nach dem C0 und wenn dies nicht vorhanden ist, nach C2 suchen? Nur hierbei wäre der zeitl. Suchaufwand wohl größer, wobei das bei den Dateigrößen wohl eh keiner merkt. Was meint ihr? |
Du solltest suchen. Dadurch dass nach dem Marker immer die Größe des Blockes kommt, kannst Du ja extrem shnell suchen. Sollte nicht auffallen. Wahrscheinlich kannst Du so danach suchen welcher zuerst kommt. Aber hier gibt es keine Garantien. :)
:cat: |
Hi Leute,
ich hab mich auch ein bisschen damit gespielt und irgendwie ist es bei mir so, dass (wenn es ein $FFC0 gibt), ich immer in den entsprechenden Bytes 160x120 als Größe habe, erst beim zweiten $FFC0 kommt die richtige Größe. Seltsame Sache, habt ihr auch so etwas ähnliches? MfG, d3g |
@ d3g: Nö, dass habe ich beim jpg nicht, wäre doch auch seltsam.
@ sakura: Wie würdest du danach suchen? Byteweise mit Read in ner Schleife auslesen? Gruß |
Was haltet ihr von folgendem Code zum Suchen?
Code:
Es fehlt natürlich noch die Abfrage, ob die Extension .jpeg oder .jpg ( mit ExtractFileExt und AnsiLowerCase) ist.
[b]procedure[/b] TForm1.Button1Click(Sender: TObject);
[b]var[/b] bild: integer; dmy: [b]array[/b][0..3] [b]of[/b] Char; [b]begin[/b] [b]If[/b] OpenDialog1.Execute [b]then[/b] [b]begin[/b] bild := FileOpen(OpenDialog1.Filename, fmOpenRead); FileSeek(bild, 0, 0); [b]Repeat[/b] FileRead(bild, dmy, 2); FileSeek(bild, -1, 1); [b]Until[/b] (Ord(dmy[0]) = 255) [b]and[/b] ((Ord(dmy[1]) = 192)[b] or [/b](Ord(dmy[1]) = 194)); FileSeek(bild, 4, 0); FileRead(bild, dmy, 4); [color=#000080][i]//Höhe[/i][/color] Label1.Caption := InttoStr(ord(dmy[0]) * 256 + ord(dmy[1])); [color=#000080][i]//Breite[/i][/color] Label2.Caption := InttoStr(ord(dmy[2]) * 256 + ord(dmy[3])); FileClose(bild); [b]end[/b]; [b]end[/b]; |
Hat jemand paar Infos über tif Dateien? Da stehen die Infos irgendwie nicht gerade am Anfang.
|
So, ich verzweifel langsam echt an den tif bzw. tiff Teilen. Ich finde da nichts darüber raus. :cry:
|
Ich hätte folgende Info über den Aufbau, habe zur Zeit aber nicht die Zeit, mir das genauer anzuschauen. Vielleicht hilft es ja.
Code:
...:cat:...
Header:
0000 Byte Order 4D4D 0002 Version 002A 0004 1st IFD pointer 00000014 IFD: 0014 Entry Count 000D 0016 NewSubfileType 00FE 0004 00000001 00000000 0022 ImageWidth 0100 0004 00000001 000007D0 002E ImageLength 0101 0004 00000001 00000BB8 003A Compression 0103 0003 00000001 8005 0000 0046 PhotometricInterpretation 0106 0003 00000001 0001 0000 0052 StripOffsets 0111 0004 000000BC 000000B6 005E RowsPerStrip 0116 0004 00000001 00000010 006A StripByteCounts 0117 0003 000000BC 000003A6 0076 XResolution 011A 0005 00000001 00000696 0082 YResolution 011B 0005 00000001 0000069E 008E Software 0131 0002 0000000E 000006A6 009A DateTime 0132 0002 00000014 000006B6 00A6 Next IFD pointer 00000000 Fields pointed to by the tags: 00B6 StripOffsets Offset0, Offset1, ... Offset187 03A6 StripByteCounts Count0, Count1, ... Count187 0696 XResolution 0000012C 00000001 069E YResolution 0000012C 00000001 06A6 Software "PageMaker 3.0" 06B6 DateTime "1988:02:18 13:59:59" Image Data: 00000700 Compressed data for strip 10 xxxxxxxx Compressed data for strip 179 xxxxxxxx Compressed data for strip 53 xxxxxxxx Compressed data for strip 160 |
Du kannst auch mal in die
![]() |
Naja, ehrlich gesagt bringt mich die GraphicEx Unit auch nicht weiter, da die entsprechenden proceduren sehr komplex sind und ich deren Inhalt somit leider nicht wirklich verstehe.
|
Hi
Also mittlerweile habe ich heraus, dass folgendes Schema bei tif Dateien gilt. :D Irgendwann kommt folgende Bytefolge: 14 0 0 1 3 0 1 und 4 Bytes danach kommt die Breite (1.Byte Rest, 2. *256) und 12 Bytes danach (dazwischen auch wieder 1,3,0,1) kommt die Höhe (1.Byte Rest, 2. *256) Gruß |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:05 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz