Suche Informationen zu Grafik-Headern

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Ynnus
Beiträge: 855
Registriert: 29.08.2004 01:37
Kontaktdaten:

Suche Informationen zu Grafik-Headern

Beitrag von Ynnus »

Hallöchen hier im neuen Forum,

ich bin gerade dabei, eine Procedure zu verfassen, welche anhand der Header von Grafikdateien wie bmp, jpeg, png und gif die Größe in Pixel ausgibt. Dabei sollen die Dateien also nicht durch loadimage() geladen werden und per imageheight() ausgelesen werden, sondern anhand der Header möcht ich die Infos erhalten.
Bisher funktioniert das mit dem BMP-Format auch schon, da die Infos in Form von Long-Werten an der Stelle 18 - 22 und 22 - 25 stehen...
Das Problem stellen die anderen Formate da. Für das BMP Format hab ich eine Vorlage, wie der Header aussieht, und wo sich die Werte für die Bildgröße befinden. Für die anderen Dinge fehlt mir diese Vorlage. Deshalb frag ich hier mal, hat jemand Infos zu den Header von den oben genannten Formaten? Ich hab schon ne Menge gegooglet und dabei kam nichts anständiges raus. Wäre nett wenn mir da jemand helfen könnte. ;)
Öhm, sollte das vielleicht ins Grafik-Forum? Eigentlich wäre das hier ein Fall für das Theorie-Forum, welches es leider nicht mehr gibt... Aber so viel mit Grafik hat es ja nicht zu tun, ich such ja nur Infos zu den Headern.


mfg.

Sunny


BTW. Toll, erster der hier im "Allgemein"-Forum wieder einmal Hilfe benötigt, bin ich... :coderselixir:
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

Benutzeravatar
Ynnus
Beiträge: 855
Registriert: 29.08.2004 01:37
Kontaktdaten:

Beitrag von Ynnus »

Vielen Dank erstmal für den Link, da gibts tatsächlich eine Menge Infos zu allen Möglichen Formaten. Leider gerade zum PNG Format, welches das wichtigste ist, nur Links welche mir nicht wirklich weiterhelfen. Die gelinkten Seiten sind derart groß und unübersichtlich, dabei will ich doch nur den Header haben und nicht Infos zur History, Entwickler, Kompression und co... :(
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag von Zaphod »

ein kurzes googeln brachte das hervor

signature \211PNG\r\n\032\n 8-bytes
chunksize 0x0000000D 4 bytes big-endian binary
chunkid "IHDR" 4 bytes
width 4 bytes big-endian binary
height 4 bytes big-endian binary - 23.


also bytes 16 - 19 ist die breite
20 - 23 ist die höhe
Benutzeravatar
Ynnus
Beiträge: 855
Registriert: 29.08.2004 01:37
Kontaktdaten:

Beitrag von Ynnus »

Das hab ich leider schon ausprobiert und kam da auf kein Ergebnis. Das sind übergroße Werte welche keinen Sinn ergeben. Ich hab mal einige Stellen per Hexeditor gecheckt und kam da auf 19 für den Horizontalen Wert. Aber der Verticale, welcher bei 23 beginnen müsste (Auch laut Hexeditor), stimmt nicht... Da kommt dann wieder ein mega-langer Long-Wert raus... Bei 4 Byte müssten es doch long sein, oder? Der Horizontale wird ja auch korrekt ausgelesen, in der einen Test-PNG-Datei die ich hier habe.

So sieht der Code bisher aus:

Code: Alles auswählen

#HL_Vertical = 0
#HL_Horizontal = 1

Procedure GetImageSize(file.s, flag.b)
  If ReadFile(0, file.s)
    If GetExtensionPart(file.s) = "bmp" Or GetExtensionPart(file.s) = "BMP"
      If flag = #HL_Horizontal
        FileSeek(18)
        ProcedureReturn ReadLong()
      ElseIf flag = #HL_Vertical
        FileSeek(22)
        ProcedureReturn ReadLong()      
      EndIf
    ElseIf GetExtensionPart(file.s) = "png" Or GetExtensionPart(file.s) = "PNG"
      If flag = #HL_Horizontal
        FileSeek(19)
        ProcedureReturn ReadLong()
      ElseIf flag = #HL_Vertical
        FileSeek(23)
        ProcedureReturn ReadLong()      
      EndIf
    EndIf
  EndIf
EndProcedure


Debug GetImageSize("xxx.png", #HL_Horizontal)
Debug GetImageSize("xxx.png", #HL_Vertical)

Zum Testen benötigt man natürlich ein PNG-Image welches xxx.png heißt. ;)
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag von Zaphod »

ich habe grade keine zeit das auszuprobieren, aber müßtest du nicht

FileSeek(16) schreiben?
Benutzeravatar
redacid
Beiträge: 581
Registriert: 29.08.2004 17:06

Beitrag von redacid »

4.1. Critical Chunks

All implementations must understand and successfully render the
standard critical chunks. A valid PNG image must contain an IHDR
chunk, one or more IDAT chunks, and an IEND chunk.

4.1.1. IHDR Image Header

The IHDR chunk must appear FIRST. It contains:

Width: 4 bytes
Height: 4 bytes
Bit depth: 1 byte
Color type: 1 byte
Compression method: 1 byte
Filter method: 1 byte
Interlace method: 1 byte

Width and height give the image dimensions in pixels. They are
4-byte integers. Zero is an invalid value. The maximum for each
is (2^31)-1 in order to accommodate languages that have
difficulty with unsigned 4-byte values.
Keine Ahnung, warum dies so ist, aber ich gehe davon aus, dass die Position eines Chunks innerhalb der Datei nicht immer gleich ist. Dies war früher bei ILBM-IFF (standard Amiga Dateiformat für Bilder) schon so. Man musste quasi nach dem passenden Chunk erst suchen, hier muss man z.B. nach dem Header-Chunk ("IHDR") suchen. Bei einer von mir mit Hex-Editor untersuchten PNG-Datei war der horizontale Wert z.B. in den Bytes 16-19 zu finden.
Benutzeravatar
Ynnus
Beiträge: 855
Registriert: 29.08.2004 01:37
Kontaktdaten:

Beitrag von Ynnus »

Bei mir war es, wie gesagt, bei 19 und 23. Wenn ich diese beiden Werte per Hex Edit erhöht habe, konnte ich damit die Größe der PNG-Datei ändern. Und wenn ich die 19 einlese, dann klappt das auch korrekt. Allerdings kommt bei der 23 ein ganz seltsamer Wert raus der ebene leider nicht stimmt. Keine Ahnung wieso... :coderselixir:

\\EDIT: @ Redacid:
Hast du es mit dem Code von mir ausprobiert, ob er die Werte korrekt einließt. Wenn du weißt wo die Bytes für die Größen sind, müsste es doch gehen, oder du kannst es zumindest mal testen. ;)
Bei mir gklappt es zwar nicht, aber vielleicht läuft es bei dir. Wenn da auch nicht, muss es ein anderes System geben, bei diesen PNG Dateien...

BTW.: Nur um Verwirrung zu verhindern, du bist doch J-The-Grey nur mit anderem Nick, oder wie? Oder ist die Ähnlichkeit nur zufällig? :?

\\EDIT2: Hab gerade deine SIg gelesen, da klärt sich das natürlich... Dachte schon hier wäre ein neuer Mod hinzugekommen.^^
Benutzeravatar
redacid
Beiträge: 581
Registriert: 29.08.2004 17:06

Beitrag von redacid »

Ich habe die Signatur noch etwas deutlicher herausgestellt, dann sollte es nicht mehr so schnell Komplikationen geben :-).

Getestet habe ich deinen Code auch -> Horizontal funktioniert, vertikal nicht. :? . Mehr kann ich dazu nicht sagen, es ist schon zu spät und lange testen möchte ich nun auch nicht mehr.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Noch ein anderer kleiner Tipp:
Änder mal diese Zeile...

Code: Alles auswählen

If GetExtensionPart(file.s) = "bmp" Or GetExtensionPart(file.s) = "BMP"
...in folgende Zeile um...

Code: Alles auswählen

If LCase(GetExtensionPart(file.s)) = "bmp"
..., damit auch "Bmp", "BMp", "BmP", "bmP", usw. erkannt wird...
Analog natürlich auch das gleiche mit "png".
Oder fange das ganze gleich so an:

Code: Alles auswählen

Select LCase(GetExtensionPart(file.s))
  Case "bmp"
  Case "png"
EndSelect
Antworten