Hallo,
ich möchte gerne in C die PixelDaten aus einer Bitmap auslesen.
Hier habe ich aber anscheinend noch Probleme mit der Position der Daten.
1
Read file DREIECK.BMP
2
FileHeader.file_type (BM).
3
FileHeader.file_size (0).
4
FileHeader.offset_data (2621440).
5
FileHeader.size (40).
6
FileHeader.width (64).
7
FileHeader.height (64).
8
FileHeader.planes (1).
9
FileHeader.bit_count (24).
10
FileHeader.compression (0).
11
FileHeader.size_image (12288).
12
FileHeader.x_pixels_per_meter(0).
13
FileHeader.y_pixels_per_meter (0).
14
FileHeader.colors_used (0).
15
FileHeader.colors_important (0).
16
DATA_OFFSET 54
17
DATA_OFFSET read 2621440
18
data parsed
Ich habe gedacht, dass zum schluss das ein oder andere mal wenigstens
eine ausgabe kommt.
Aber wie man sieht kommt da ncihts.
auch wenn ich für das offset i fseek die 2621440 nehme, bekomme ich kein
printf.
Hallo Chandler,
du möchtest den Header der BMP-Datei in Structs abbilden. Das geht
schief, da der Compiler ein sogenanntes Alignment anwenden darf. Es
werden also ggf. Füllbytes in die Struktur eingefügt. AFAIK kann der
Compiler sogar die Reihenfolge der Elemente ändern (sie stehen dann
anders im Speicher als in der Struktur-Deklaration).
Leider kenne ich die (Compiler-) Einstellungen bzw. pragmas nicht, um
das Alignment zu umgehen. Das werden andere hier jedoch sicher bald
ergänzen.
WIMRE ist es allerdings besser, die Strukt-Elemente einzeln zu füllen.
Dast Du die Datei mal im Hex-Editor angeschaut? Dann siehst Du schnell,
ob der Header Deinen Erwartungen entspricht und wie die Daten dann in
der Struktur abgelegt werden.
ciao
Marci
Marci W. schrieb:> Dast Du die Datei mal im Hex-Editor angeschaut? Dann siehst Du schnell,> ob der Header Deinen Erwartungen entspricht und wie die Daten dann in> der Struktur abgelegt werden.
Das war ein guter tipp.
Habe es "jetzt" gemacht und gesehen, dass es nicht wirklich passt.
file_type = "BM" und einige andere Werte (im infoHeader) wurde mir immer
valide ausgegeben. Bin daher ausgegangen, dass es überallpasst. aber
Anscheinend passt es doch nicht überall.
Marci W. schrieb:> Leider kenne ich die (Compiler-) Einstellungen bzw. pragmas nicht, um> das Alignment zu umgehen.
Bei MS z.B. #pragma pack, bei gcc __attribute__((packed)) - Details
stehen in der Dokumentation.
Marci W. schrieb:> WIMRE ist es allerdings besser, die Strukt-Elemente einzeln zu füllen.
In erster Linie ist es mühsamer.
Harald K. schrieb:> In erster Linie ist es mühsamer.
Das stimmt allerdings! Man muss jedoch aufpassen, da bei der Verwendung
von "packed" je nach Prozessorarchitektur ein Pointer Misalignment
auftreten kann. So gesehen ist der TO mit den einzelnen reads auf der
sicheren Seite und plattformunabhängig (OK, es könnte noch Probleme wg.
Endianess etc. geben) ;-)
ciao
Marci
Marci W. schrieb:> AFAIK kann der> Compiler sogar die Reihenfolge der Elemente ändern (sie stehen dann> anders im Speicher als in der Struktur-Deklaration).
Können tut er das freilich.
Dürfen aber nicht.
Hallo,
ganz möchte es doch noch nicht so hinhauen.
beim Auslesen der Daten kommt doch noch irgendwas durcheinander.
Damit ich mich einfacher tue, habe ich ein neues Bild erstellt (2x3
Pixel)
Zum schluss möchte ich mir dann mit printf das bild in der Console
nachstellen
also das G würde ich verstehen. Das ist unten links.
p wäre schräg davon. auch wird mir nur ein Wert ausgegeben, obwohl die
for-schleife eigentlich über alles drüber gehen sollte.
Chandler B. schrieb:> for(uint8_t x=0; x<2-1; x++)> {> for(uint8_t y=0; y<3-1; y++)> {
Wozu soll denn das -1 sein? Ist es gewollt, dass die äußere Schleife nur
einmal durchläuft und die innere zweimal?
Rolf M. schrieb:> Wozu soll denn das -1 sein? Ist es gewollt, dass die äußere Schleife nur> einmal durchläuft und die innere zweimal?
nein, das war ein Fehler
Habe mir das Bild noch einmal im Hexeditor angesehen.
Es scheint so zu sein,
dass drei Bytes Farbe kommen (reihenfolge Blau, Grün, Rot), dann noch
einmal drei Bytes Farbe (reihenfolge Blau, Grün, Rot) und dann zwei
Bytes 0x00 da sind.
Compression = 0 (BI_RGB): Bilddaten sind unkomprimiert, bedeutet
"Jede Bildzeile ist durch rechtsseitiges Auffüllen mit Nullen auf ein
ganzzahliges Vielfaches von 4 Bytes ausgerichtet." (Wikipedia)
Heißt, da ich 6 Bytes Farbdaten habe (2 pixel x 3Bytes/Pixel), bleiben 2
Bytes übrig um auf 8 Bytes (vielfaches von 4 Bytes) zu kommen.
Chandler B. schrieb:> wenn ich die größe des Bildes nicht genau weiß.
Die Größe, etc. steht doch im Header.
Chandler B. schrieb:> FileHeader.width (64).> FileHeader.height (64).
Der Threadstarter hat mit keinem Wort verraten, worauf sein Programm
laufen soll. Die #includes in seinem Sourcefile lassen so etwas wie
Linux vermuten, jedenfalls nicht den Betrieb auf einem µC.
Also könnte man auch eine der zig bestehenden Libraries verwenden, um
Bilddateien zu lesen, die würden auch die vielen Möglichkeiten
unterschiedlichster BMP-Formate erschlagen. Denn BMP ist letztlich nur
ein Containerformat, da kann alles mögliche drinstecken.
Und mit so einer Library wie z.B. https://libgd.github.io/ kann man dann
auch gleich ganz andere Dateiformate verarbeiten.
Wenn das ganze aber eine Übung im Selbstverarbeiten komplexer
Dateiformate sein soll: Header lesen und interpretieren. Dazu die
Dokumentation genau ansehen.
https://learn.microsoft.com/en-us/windows/win32/gdi/bitmaps
Chandler B. schrieb:> Muss ich dann jetzt mal weiterschauen, wie ich das machen kann, wenn ich> die größe des Bildes nicht genau weiß.
Witzig. Genau dafür, dass man das halt sicher weiß, gibt's ja den
Header. Der beschreibt, wie die Nutzdaten des Bildes zu interpretieren
sind.
Übrigens: biCompression == BI_RGB kennt auch noch ziemlich viele
Unterformate. Du hast nur eins davon (RGB24) implementiert. Das ist zwar
recht verbreitet, aber es gibt auch andere, die sehr weit verbreitet
sind.
Sehr häufig wird z.B. RGB32 benutzt, weil es einen Alpha-Kanal besitzt.
Auch recht häufig anzutreffen sind Monochrom- (AKA: "Schwarzweiß"-)
Bitmaps.
Und nicht zuletzt: auch eins der "alten" indizierten Formate ist noch
weit verbreitet: die Variante mit 8Bit-Palettenindizes. Das wird sowohl
für Graustufenbilder als auch für (relativ) platzsparende farbige Icons
verwendet.
Dazu kommen noch die (allerdings sehr viel seltener verwendeten) Formate
mit Bitmasken und wie z.B. RGB565, RGB555, ARGB1555 und RGB332 mit 16
bzw. 8 Bit pro Pixel. Wenn überhaupt heute noch relevant, dann am
ehesten im Bereich µC-Programmierung von einem Windows-PC aus.
Harald K. schrieb:> Der Threadstarter hat mit keinem Wort verraten, worauf sein Programm> laufen soll. Die #includes in seinem Sourcefile lassen so etwas wie> Linux vermuten, jedenfalls nicht den Betrieb auf einem µC.
Wir sind im Unterforum "PC-Programmierung". Da würde ich sowieso nicht
von einem µC ausgehen.
Rolf M. schrieb:> Wir sind im Unterforum "PC-Programmierung".
So präzise, wie hier Threads von den Verfassern in irgendwelche
Forenbereiche einsortiert werden (z.B. "Restaurierung eines verrosteten
Funkgeräts" unter "Projekte & Code" oder "Rasenmäherakku" unter
"Platinen"), würde ich darauf nicht allzuviel geben.