2016-06-06 23 views
0

Ich versuche, die Anzahl der Bits pro Pixel in einer BMP-Datei zu erhalten. Laut Wikipedia soll es am 28. Byte liegen. So nach dem Lesen einer Datei:C++ - Anzahl der Bits pro Pixel aus BMP-Datei lesen

// Przejscie do bajtu pod ktorym zapisana jest liczba bitow na pixel 
     plik.seekg(28, ios::beg); 

     // Read number of bytes used per pixel 
     int liczbaBitow; 
     plik.read((char*)&liczbaBitow, 2); 

     cout << "liczba bitow " << liczbaBitow << endl; 

Aber liczbaBitow (Variable, die Anzahl von Bits, soll pro Pixelwert halten) ist -859.045.864. Ich weiß nicht, woher es kommt ... Ich bin ziemlich verloren.

Irgendwelche Ideen?

+0

Sie müssen zeigen, wie die Datei geöffnet wurde.Wurde es mit dem Flag 'ios :: binary' geöffnet? – PaulMcKenzie

+0

Sie setzen zwei Bytes in eine unititialisierte (möglicherweise 4 Byte lange) Ganzzahl. Versuchen Sie, 'liczbaBitow' als ersten Schritt auf Null zu initialisieren. – Machtl

+0

Das [Bitmap-Dateiformat] (https://msdn.microsoft.com/en-us/library/dd183391.aspx) ist ** übrigens ** zu komplex, um einen eigenen Parser zu schreiben. Verwenden Sie eine Bibliothek, die entweder in Ihre Plattform integriert ist, oder eine Bibliothek eines Drittanbieters. – IInspectable

Antwort

2

-859045864 kann in Hexadezimal als 0xCCCC0018 dargestellt werden.

Das Lesen des zweiten Bytes gibt uns 0x0018 = 24bpp.

Was hier am wahrscheinlichsten passiert, ist, dass liczbaBitow auf 0xCCCCCCCC initialisiert wird; während Ihre plik.read nur die unteren 16 Bits schreibt und die oberen 16 Bits unverändert lässt. diese Zeile ändern soll dieses Problem beheben:

int liczbaBitow = 0;

Obwohl, vor allem mit so etwas, es ist am besten, einen Datentyp zu verwenden, die genau Ihre Daten übereinstimmt:

int16_t liczbaBitow = 0;

Dies kann gefunden werden in <cstdint>.

+1

Sie könnten hinzufügen, dass der msvc-Compiler im Debug-Modus je nach Typ ganzzahlige Typen mit '0xCCCCCCCC' oder mehr initialisiert. – Machtl

+1

@Machtl Danke, ich habe mehr Details hinzugefügt, die die Antwort erklären. – Thebluefish

+0

Vielen Dank Jungs! Schätze es wirklich. – MindRoller

3

Um @ TheBluefish Antwort zu klären, dieser Code hat den Fehler

// Read number of bytes used per pixel 
int liczbaBitow; 
plik.read((char*)&liczbaBitow, 2); 

Wenn Sie (char*)&libczbaBitow verwenden, werden Sie die Adresse einer 4-Byte-Integer übernimmt und sagen Sie den Code 2 Byte dort zu setzen.

Die anderen zwei Byte dieser Ganzzahl sind nicht angegeben und nicht initialisiert. In diesem Fall sind sie 0xCC, da dies der Stack-Initialisierungswert ist, der vom System verwendet wird.

Aber wenn Sie dies von einer anderen Funktion oder wiederholt aufrufen, können Sie erwarten, dass der Stapel andere gefälschte Werte enthält.

Wenn Sie die Variable initialisieren, erhalten Sie den erwarteten Wert.

Aber es gibt einen anderen Fehler .. Byte-Reihenfolge ist auch hier wichtig. Dieser Code geht davon aus, dass die native Byte-Reihenfolge der Maschine genau der Byte-Reihenfolge aus der Dateispezifikation entspricht. Es gibt eine Reihe von verschiedenen Bitmap-Formate, sondern von Ihrer Referenz, die Wikipedia-Artikel sagt:

alle ganzzahligen Werte gespeichert sind, in Little-Endian-Format (das heißt am wenigsten signifikante Byte zuerst).

Das ist das gleiche wie deins, das ist offensichtlich auch x86 Little Endian. Andere Felder sind nicht als Little Endian definiert. Wenn Sie also das Bild dekodieren, müssen Sie darauf achten.

Idealerweise würden Sie in ein Bytearray einlesen und die Bytes dort platzieren, wo sie hingehören. Siehe Convert Little Endian to Big Endian

int libczbaBitow; 
unsigned char bpp[2]; 
plik.read(bpp, 2); 
libczbaBitow = bpp[0] | (bpp[1]<<8);