Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Bildgröße von Bilddateien (https://www.delphipraxis.net/394-bildgroesse-von-bilddateien.html)

Tpercon 13. Jul 2002 10:13


Bildgröße von Bilddateien
 
Wie kann man die Bildgröße (Breite und Höhe) von jpg, jpeg, gif und png Dateien ermitteln?

Daniel B 13. Jul 2002 10:38

Re: Bildgröße von Bilddateien
 
Zitat:

Zitat von Tpercon
Wie kann man die Bildgröße (Breite und Höhe) von jpg, jpeg, gif und png Dateien ermitteln?

Hi,

.tiff und .ico nicht vergessen.

Luckie 13. Jul 2002 16:29

@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:

Daniel B 13. Jul 2002 18:01

Zitat:

Zitat von Luckie
@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:

Ups, hab nicht aufgepasst. Es ist ja auch so klein geschrieben. Sorry. Wo war es denn drin?

sakura 13. Jul 2002 20:36

Das ist im allgemeinen anders für jeden Typ. Bei www.wotsit.org findest Du die Definitionen. Der Rest ist Handarbeit.

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.

movax 13. Jul 2002 20:40

@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 wotsit.org nach, da gibt'S auch einige texte zu Gif-Dateien.

greetz,
-movax-

|movax.rult.de

Tpercon 17. Jul 2002 19:33

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.

movax 17. Jul 2002 20:13

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 ;)

Tpercon 17. Jul 2002 20:23

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.

sakura 18. Jul 2002 10:04

Hi,

also GIF ist recht einfach. Infos von www.wotsit.org. Erst einmal der allgemeine Aufbau
Code:
        +-----------------------+
        | +-------------------+ |
        | |   GIF Signature  | |
        | +-------------------+ |
        | +-------------------+ |
        | | Screen Descriptor | |
        | +-------------------+ |
        | +-------------------+ |
        | | Global Color Map | |
        | +-------------------+ |
        . . .              . . .
        | +-------------------+ |    ---+   
        | |  Image Descriptor | |       |   
        | +-------------------+ |       |   
        | +-------------------+ |       | 
        | |  Local Color Map | |       |-   Repeated 1 to n times
        | +-------------------+ |       |   
        | +-------------------+ |       |   
        | |    Raster Data   | |       |   
        | +-------------------+ |    ---+   
        . . .              . . .  
        |-    GIF Terminator  -|   
        +-----------------------+
Die GIF Signatur ist immer folgender Aufbau:

GIF87a, also drei Bytes für "GIF" und drei für die Version. Anschließend kommt der "Screen Discriptor"
Code:
         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)
        +---------------+
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.
:cat:

movax 18. Jul 2002 10:09

also dann.. ich hab mich mal hingesetzt und schnell was für dich zusammengeschustert:

Code:
[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];
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 ;))

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.rult.de

sakura 18. Jul 2002 10:11

@movax: Ich bin mir sicher: Tpercon wirds danken. :)
:cat:

Tpercon 18. Jul 2002 17:16

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?

Tpercon 19. Jul 2002 20:03

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

sakura 20. Jul 2002 07:34

Eine Regelmäßigkeit gibts schon, aber die hat ein paar verschiedene Abhängigkeiten...
Code:
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
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.

Code:
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)
:cat:

Tpercon 22. Jul 2002 15:35

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ß

sakura 22. Jul 2002 16:07

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

Tpercon 22. Jul 2002 17:09

Habt ihr den jpeg Dateien wo das nicht C2 ist?

Christian Seehase 22. Jul 2002 17:12

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.

Tpercon 22. Jul 2002 17:23

Prinzipiell hast du natürlich recht!
Die ersten 10 Byte's sind bei beiden gleich. Mich würde es halt trotzdem interessieren.

sakura 22. Jul 2002 18:06

Kurz: ja, ich speichere meine JPG files oft mit JPEG
:cat:

Tpercon 22. Jul 2002 20:04

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?

sakura 23. Jul 2002 06:51

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:

d3g 23. Jul 2002 13:26

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

Tpercon 23. Jul 2002 14:38

@ 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ß

Tpercon 23. Jul 2002 17:36

Was haltet ihr von folgendem Code zum Suchen?

Code:
[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];
Es fehlt natürlich noch die Abfrage, ob die Extension .jpeg oder .jpg ( mit ExtractFileExt und AnsiLowerCase) ist.

Tpercon 23. Jul 2002 18:47

Hat jemand paar Infos über tif Dateien? Da stehen die Infos irgendwie nicht gerade am Anfang.

Tpercon 29. Jul 2002 11:52

So, ich verzweifel langsam echt an den tif bzw. tiff Teilen. Ich finde da nichts darüber raus. :cry:

sakura 29. Jul 2002 12:08

Ich hätte folgende Info über den Aufbau, habe zur Zeit aber nicht die Zeit, mir das genauer anzuschauen. Vielleicht hilft es ja.

Code:
          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
...:cat:...

jbg 29. Jul 2002 12:18

Du kannst auch mal in die GraphicEx Unit schauen. Dort werden so einige Grafikformate eingelesen.

Tpercon 29. Jul 2002 13:24

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.

Tpercon 1. Aug 2002 19:26

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 08:37 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz