BITMAPFILEHEADER und BITMAPINFOHEADER Strukturen...
-
Hi,
wenn ich unter Windows eine Bitmap selbst erstellen und abspeichern will, kann ich ja die beiden oben genannten Strukturen ausfüllen, diese an den Anfang einer Datei schreiben und anschließend meine Bilddaten schreiben. Das funktioniert auch wunderbar. Allerdings soll mein Programm plattformunabhängig sein, deshalb habe ich mir die beiden Strukturen selbst definiert, genauso wie sie in der Dokumentation stehen. Das sieht bei mir unter Win32 dann so aus:
typedef struct tagBITMAPFILEHEADER { unsigned short bfType; unsigned long bfSize; unsigned short bfReserved1; unsigned short bfReserved2; unsigned long bfOffBits; } BITMAPFILEHEADER; typedef struct tagBITMAPINFOHEADER{ unsigned long biSize; long biWidth; long biHeight; unsigned short biPlanes; unsigned short biBitCount; unsigned long biCompression; unsigned long biSizeImage; long biXPelsPerMeter; long biYPelsPerMeter; unsigned long biClrUsed; unsigned long biClrImportant; } BITMAPINFOHEADER;Original stehen folgende Datentypen da:
- DWORD anstelle von unsigned long
- WORD anstelle von unsigned short
- LONG anstelle von longDa ich aber unter Win32 bin, sind die oben genannten Typen (also DWORD,WORD,LONG) aber exakt so als Typedef definiert wie ich es jetzt geschrieben habe, deshalb sollte das ja keine Probleme geben.
Tja und das Problem ist jetzt halt, dass so doch nicht funktioniert. Die Bitmaps die damit erstellt werden können nicht geöffnet werden, weil irgendwas mit dem Bitmap-Header nicht stimmt. Ich hab nur absolut keine Ahnung woran das liegen könnte. Jemand eine Idee?
-
Ich würde zuallererst das Padding prüfen.
-
Erstens: Padding (zumindest für die Header-Typen) ausschalten - sonst kommt der Compiler auf die Idee, Füllbytes zwischen die Daten zu quetschen (z.B. zwischen bfType und bfSize).
Zweitens: short und long sind laut Standard mindestens 2 bzw. 4 Byte groß, dürfen aber auch größer sein - du brauchst int-Typen, die genau 2 (WORD) bzw. 4 (DWORD/LONG) Byte groß sind.
Drittens: Hast du die Header auch korrekt mit Werten gefüllt (z.B. bfType==19778 ("BM") oder biSize==40)?
-
Argh, hab gar nicht an das Padding gedacht.
Lag am Padding. Jetzt funktioniert es.
Danke
-
Mal so interesse halber:
Wie schaltet man das Padding denn ab?
-
#pragma pack(1) // Ausrichtung auf Byte-Grenzen (Padding ausschalten) struct xyz // Strukturen deklarieren { ... }; #pragma pack() // Standard Padding wieder herstellen
-
Wissen haben wollender schrieb:
Wie schaltet man das Padding denn ab?
Das hängt vom verwendeten Compiler ab (Zausel's Variante ist für den MSVC gültig).
-
was gibts denn sonst noch für varianten
-
Der BCC akzeptiert die MSVC-Padding-Anweisungen auch. Wer es ganz sauber machen möchte, sollte aber folgendes verwenden:
#ifdef __BORLANDC__ #pragma pack(push, n) #endif ... #ifdef __BORLANDC__ #pragma pack(pop) #endifDadurch wird das Padding hinterher nicht auf den Default- sondern auf den zuletzt eingestellten Wert gesetzt.
-
Beim g++ schreibt man einfach hinter jedes Attribut __attribute__((packed)).
Hab ich zumindest bei mir gemacht und hat funktioniert.
-
Ui!
Das es verschiedene Versionen zum 'Paddig abschalten' gibt wusste ich noch gar nicht.
Dann wäre es wohl doch besser, der Portabilität zu liebe, Paddinbytes zu benutzen ?
Aber auf was ausrichten, auf 4Byte-Grenzen ?