C - Bitmap erstellen

BolleF1

Mitglied
Hallo,
Ich versuche jetzt seid Stunden ein Bitmap zuerstellen, doch das Bitmap ,was erstellt wird lässt sich nicht öffnen.Mein Code lässt sich fehlerfrei kompillieren,deswegen kann ich auch keine Rückschlüsse auf meine Fehler ziehen.

Code:
#include <iostream>
#include <fstream>

using namespace std; 

struct BMFH { //BitMap File Header structure
unsigned short bfType; //könnte char sein
unsigned long bfSize;
unsigned short bfReserved1;
unsigned short bfReserved2;
unsigned long bfOffBits;
};

struct BMIH { //BitMap Info Header structure
unsigned long biSize;
unsigned long biWidth;
unsigned long biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned long biCompression;
unsigned long biSizeImage;
unsigned long biXPelsPerMeter;
unsigned long biYPelsPerMeter;
unsigned long biClrUsed;
unsigned long biClrImportant;
};

struct RGBQUAD{ //Palette RGBQUAD
int rgbBlue;
int rgbGreen;
int rgbRed;
int rgbReserved;
};

struct pixel { //legt die pixel sttructure fest 

unsigned short R;
unsigned short G; //RGB 
unsigned short B;
//unsigned short unused; //benötigt
};

void setfileheader(BMFH& fileheader
{ // Fileheader Einstellungen

fileheader.bfType = 19778;
fileheader.bfSize = 108;
fileheader.bfReserved1 = 0;
fileheader.bfReserved2 = 0;
fileheader.bfOffBits = 1078;

}

void setinfoheader(BMIH& infoheader) 
{ //Infoheader Einstellungen

infoheader.biSize = sizeof(infoheader);
infoheader.biWidth = 128;
infoheader.biHeight = 128;
infoheader.biPlanes = 1;
infoheader.biBitCount = 24;
infoheader.biCompression = 0;
infoheader.biSizeImage = 0;
infoheader.biXPelsPerMeter = 0;
infoheader.biYPelsPerMeter = 0;
infoheader.biClrUsed = 0;
infoheader.biClrImportant = 0;

}

int main(){

//------------Pixel setzen und co ..-//


pixel PICTAR[128][128]; //Pixelarray

int i;
int j;

for (int i=0; i<128; i++){ //Horizontal

for (int j=0; j<128; j++){ //Vertikal

PICTAR[i][j].R = 100; //rote pixel
PICTAR[i][j].G = 0;
PICTAR[i][j].B = 0;

}
}


//-------------------

ifstream::pos_type size; 
BMFH fileheader; //Fileheader
BMIH infoheader;//...

setfileheader(fileheader); //einstellungen Fileheader setzen
setinfoheader(infoheader);//...

ofstream myfile ("testbmp.bmp",ios::out | ios::binary); //Ofstream erstelllen mit Namen : myfile
//and opens it for binary input

/////////Daten schreiben///////////////
//myfile.write ((char*) &fileheader,sizeof(fileheader)); //schreibe header
//myfile.write ((char*) &infoheader,sizeof(infoheader)); //schreibe header
myfile.write ((char*) &fileheader,14); //schreibe header
myfile.write ((char*) &infoheader,40); //schreibe header
myfile.write ((char*) &PICTAR,sizeof(pixel)*128*128);
myfile.close();


}

Kann mir jemand helfen? Ich glaube von alleine komme ich nicht weiter,

Danke im Voraus!

lg BolleF1
 
Hi,

Bist du sicher das du die Header richtig eingetragen hast?

Es gibt da verschiedene Kombinationen die man beachten muss.

z.B. kann das Bild auch rückwerts gelesen werden indem man die Höhe? auf einen negativen wert setzt (statt 128, -128).

Gruß
Anfänger
 
Hallo,

Danke für deine Antwort.
Ja, bei den Headern hatte ich auch schon einen Fehler vermutet . Ich werde mich nochmal umgucken vllt. finde ich etwas.

Ich weiß nicht genau ,was du mitr deinem Beispiel bezwecken willst.
Was genau meinst du?

lg BolleF1
 
Die Bitmap-Header werden ohne pack-Angaben mit Zusatzbytes aufgefüllt. Da muss man aufpassen, daher drumrum ein struct-alignment angeben, das keine Füllbytes einsetzt. Bei Visual Studio ginge das so (aus dem Original-Windows-Header):

#include <pshpack2.h>
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
#include <poppack.h>
 
Hallo,

Ok danke für deine Hilfe,ich werde es sobald ich wieder Zeit habe ausprobieren und meine Ergebnisse dann hier posten.

lg BolleF1
 
Lösung

Hallo,
falls irgendjemand mal das Gleiche Problem hat, werde ich hier mal meine Lösung posten.

Mit diesem Code wird eine zufälliges Bitmap erstellt mit der Größe 128*128.

Code:
#include <iostream>
#include <fstream>

using namespace std; 

struct BITMAPFILEHEADER { //BitMap File Header structure
unsigned short bfType; 
unsigned long bfSize;
unsigned short bfReserved1;
unsigned short bfReserved2;
unsigned long bfOffBits;
};

struct BITMAPINFOHEADER { //BitMap Info Header structure
unsigned long biSize;
unsigned long biWidth;
unsigned long biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned long biCompression;
unsigned long biSizeImage;
unsigned long biXPelsPerMeter;
unsigned long biYPelsPerMeter;
unsigned long biClrUsed;
unsigned long biClrImportant;
};

int main(){

BITMAPFILEHEADER fileheader; //Fileheader
BITMAPINFOHEADER infoheader;//...

// Fileheader Einstellungen
fileheader.bfType = 'MB';
fileheader.bfSize = sizeof(BITMAPFILEHEADER);
fileheader.bfReserved1 = 0;
fileheader.bfReserved2 = 0;
fileheader.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);

//Infoheader Einstellungen

infoheader.biSize = sizeof(infoheader);
infoheader.biWidth = 128;
infoheader.biHeight = 128;
infoheader.biPlanes = 1;
infoheader.biBitCount = 24;
infoheader.biCompression = 0;
infoheader.biSizeImage = 0;
infoheader.biXPelsPerMeter = 0;
infoheader.biYPelsPerMeter = 0;
infoheader.biClrUsed = 0;
infoheader.biClrImportant = 0;


/////////Daten schreiben///////////////
ifstream::pos_type size; 
ofstream myfile ("testbmp.bmp",ios::out | ios::binary); //Ofstream erstelllen mit Namen : myfile

myfile.write ((char*) &fileheader,sizeof(fileheader)); 
myfile.write ((char*) &infoheader,sizeof(infoheader));
for(int u=0;u<128;u++)
{
	for(int o=0;o<128;o++)
	{
		for(int z= 0;z<3;z++)
		{
		myfile.put(rand() % 256);
		}
	}
}


myfile.close();


}

Ich hoffe ich konnte euch helfen!


LG BolleF1
 
Hallo,
Ich habe jetzt noch ein Problem, und zwar erstellt mein Programm Bitmaps mit einer Bitmao Größe von 20*20 , aber nicht welche mit 43*555, ich glaube ,das liegt daran dass die Anzahl der Bytes durch 4 teilbar sein muss.Aber welche Bytes müssen durch 4 teilbar sein alle, oder nur die aus Höhe * Breite oder Höhe*Breite*3 und wo muss ich die restlichen Bytes setzen dsmit ich zum Beispiel ein Bild mit 3*3 Picxeln erstellen kann?

Danke im Voraus!

LG BolleF1
 
Du musst jede Zeile nach rechts mit 0 auffüllen, sodass sie durch 4 teilbar ist.

Code:
ui32 offset = (bmi.width * 24) / 8;
	offset %= 4;
	static char nil = '\0';
	for(int i = 0; i < abs(bmi.height); ++i)
	{
		for(int a = 0; a < bmi.width; ++a)
		{
			BGR br;
			br.b = rand() % 255;
			br.r = rand() % 255;
			br.g = rand() % 255;
			fwrite(&br, 3, 1, f);
		}
		for(int b = 0; b < offset; ++b)
		{
			fwrite(&nil, 1, 1, f);
		}
	}
 
Hallo,
Danke erstmal für deine schnelle Antwort, da ich gerade wenig Zeit habe bin ich wohl dazu gezwungen ,das heute Nachmittag auszuprobieren.

Danke BolleF1
 

Neue Beiträge

Zurück