# Bitmap Header auslesen...



## bastionmancher (28. Dezember 2007)

Hallo,
ich versuche ein Programm zu schreiben, dass den Header einer Bitmapdatei einliest und hexadezimal ausgibt. Das Programm soll also von Offset 0 bis ausschließlich Offset 54 bzw. hexadezimal 32 lesen.
Bis jetzt hab ich mir folgendes überlegt:

```
#include<iostream>
#include<fstream>
using namespace std;

int main()
{
	cout<<"Bitte geben Sie den Dateinamen einer 24-bit Bitmap Datei an (max. 15 Zeichen): "<<flush;
	char name[15];
	cin>>name;
	system("cls");
	ifstream einlesen;
	einlesen.setf(ios::hex, ios::basefield);
	einlesen.open(name, ios::in);
	string text;
	char zeichen;
	int zahl;
	while(einlesen.tellg()<54)
	{
		einlesen.get(zeichen);
		zahl=zeichen;
		cout.setf(ios::hex, ios::basefield);
		cout<<zahl<<flush;
		einlesen.seekg(1, ios::cur);
	}
	system("pause");
	return 0;
}
```
Wenn ich versuche das zeichen direkt als char auszugeben passiert gar nix. Wenn ich es wie hier erst in einen integer umwandele, kommt zwar eine Ausgabe, allerdings keine sinnvolle^^: Bei einer Testdatei wird unendlich oft 7c angezeigt...
Ich hab mir die Datei mal mit einem Hexadezimaleditor angeguckt. Die richtige Ausgabe müsste lauten:





> 424D 38A9 E600 0000 0000 3600 0000 2800 0000 200A 0000 9807 0000 0100 1800 0000 0000 02A9 E600 202E 0000 202E 0000 0000 0000 0000 0000


Ich dachte dann, dass get() wohl den einlesepunkt, weshalb auch immer, nicht verschiebt. Deshalb hab ich noch die zeile 
	
	
	



```
einlesen.seekg(1, ios::cur);
```
eingebaut, obwohl ich denke, dass sie eigentlich überflüssig sein müsste...
Ich hoffe ihr könnt mir helfen. Danke schon mal im Voraus für alle Versuche!

Gruß
bastionmancher


----------



## cymoril (5. März 2009)

Ich arbeite an einem ähnlichen Problem: Möchte aus dem Header Breite und Höhe auslesen.

Ich kann zumindest die Zeichen als char lesen und auch richtig ausgeben. (Zumindest die ersten beiden Zeichen stimmen.) Siehe:
http://www.tutorials.de/forum/c-c/336094-wie-kann-man-die-abmessungen-von-bildern-auslesen.html

Bei dir könnte folgendes die Ursache sein:
Auch in deiner Variablen Zahl wird nichts gespeichert. Deshalb wird das angezeigt, was zufällig im Speicher stand, und zwar dann immer wieder das gleiche.

Um sicher zu gehen, dass es das ist, setzt die Variable mal am Anfang auf 0, dann müsste immer 0 ausgegeben werden.

Dann kannst du dir ja mal meinen Ansatz ansehen, damit müsstest du n Schritt weiter kommen.


Ein weiteres Problem ist:
Ein Char ist 1 Byte = 8 Bit groß,
ein Hexadezimalzeichen nur 4 Bit groß.
Du müsstest also jedes Zeichen nachher splitten, z. B. mit dem &-Operator um die oberen bzw. unteren Bits zu löschen und die oberen Bit mit >> 4 nach rechts verschieben (ähnlich wie bei meinem Programm).
Dann müsstest du theoretisch (Dezimal-) Zahlen zwischen 0 und 15 bekommen. (Aber wie gesagt: Bei mir kommt auch noch nicht das richtige raus.)


----------



## engelmarkus (5. März 2009)

Ihr könntet ja mal hier spicken: http://www.kalytta.com/bitmap.h
Dort wird ein struct verwendet, um auf einzelne Elemente des Headers zuzugreifen.


----------



## deepthroat (12. März 2009)

Hi.





bastionmancher hat gesagt.:


> Hallo,
> ich versuche ein Programm zu schreiben, dass den Header einer Bitmapdatei einliest und hexadezimal ausgibt. Das Programm soll also von Offset 0 bis ausschließlich Offset 54 bzw. hexadezimal 32 lesen.
> Bis jetzt hab ich mir folgendes überlegt:
> 
> ...


in deinem Programm sind einige Fehler und auch unnötiger Code enthalten.


die setf Methode für den *einlesen *Stream aufzurufen bringt gar nichts, da diese Einstellungen nur für *formatierte *Ein-/Ausgaben verwendet werden. (d.h. wenn man die << bzw. >> Operatoren benutzt)
du führst keinerlei Prüfung der Eingabeoperationen durch. Woher willst du denn wissen, ob überhaupt etwas eingelesen wurde?
du öffnest den Stream im Textmodus, möchtest aber Binärdaten auslesen. Du mußt den Stream dann natürlich auch im Binärmodus öffnen.
das seekg() ist unnötig. Du überspringst dabei immer ein Byte.
da ein char vorzeichenbehaftet sein könnte, solltest du den Wert in einen nicht-vorzeichenbehafteten Wert umwandeln.
Gruß


----------



## devDevil (12. März 2009)

cymoril: Das wäre der Fall, wenn get fehlschlagen würde.

```
#include<iostream>
#include<fstream>
using namespace std;

int main()
{
	cout<<"Bitte geben Sie den Dateinamen einer 24-bit Bitmap Datei an (max. 15 Zeichen): "<<flush;
	char name[15]; // nimm std::string, dann haste die beschränkung nicht ...
	cin>>name;
	system("cls"); // pfui! außerdem: wo ist <cstdio> u. std:: vor system? ;)
	ifstream einlesen; // jap das ding hat nen c-tor mit parametern ... 
	einlesen.setf(ios::hex, ios::basefield); // ?! lass den quatsch komplett weg ...
	einlesen.open(name, ios::in); // s.o.
	string text; // wooofür?
	char zeichen;
	int zahl; // nja ne extra variable, nur damit dann char zu int implizit statt explizit gecastet wird... ich weiß nicht ;)
	while(einlesen.tellg()<54)
	{
		einlesen.get(zeichen); // dann guck auch ob's geklappt hat?!
		zahl=zeichen; // s.o.
		cout.setf(ios::hex, ios::basefield); // schon vernünftiger als der mist oben ;) aber hier <iomanip> und std::hex einfach nutzen!
		cout<<zahl<<flush; // ob du hier flushen musst? ... denke nicht ;)
		einlesen.seekg(1, ios::cur); // und hoppsa eins übersprungen ... get schiebt den lesezeiger schon um 1 nach vorne ;)
	}
	system("pause"); // s.o. aber hier einfach std::cin.ignore();
	return 0; // und weeeeg!
}
```
 So dann is die Frage ... binary-mode die Datei öffnen ... ja/nein?
Alles auf einmal einlesen und dann auf einmal alles ausgeben ... ja/nein?
Testen ob Bitmapdatei ... ja/nein?

Mal die beiden Fragen mit nein beantwortet ergäbe sich:

```
#include <string>
#include <iostream>
#include <cstdio>
#include <fstream>
#include <iomanip>

int main()
{
    std::cout<<"Dateiname: ";
    std::string filename;
    std::getline(std::cin, filename);
    
    std::ifstream file_stream(filename.c_str());
    if (!file_stream) return std::cerr << "Datei konnte nicht geöffnet werden!" << std::endl, 1;

    while (file_stream && file_stream.tellg() <= 54)
        std::cout << std::hex << static_cast<unsigned int>(file_stream.get());
}
```
 ...
hab vorsichtshalber mal nen test ob die datei gelesen werden kann eingebaut


----------

