[VC++] Laden einer Bitmap & Header auslesen

Bl@ckD0G

Lieutenant
Registriert
Nov. 2002
Beiträge
730
Hi!

ich bin gerade dabei eine kleine Applikation in MFC zu schreiben und möchte damit jetzt auch BMPs laden. Nur vorab, ich bin MFC-Rookie!
Das klappt soweit eigentlich auch schon, nur sind die Bilder etwas verschoben und auf dem Kopf.
Woran das liegt ist mir eigentlich klar: der Header wird nicht richtig oder garnicht ausgelsen.

Ich weiß allerdings nicht, wie ich den Header richtig auslesen kann, und wie ich auf die biWidth und biHeight ran kommen.
Habe mir auch schon eine BitmapInfoHeader Struktur erstellt, aber richtig klappen will das noch nicht...
Hier mal die Fkt, die mir die Datei öffnet und anzeigt.
Code:
void CUebung3View::OnFileOpen() 
{

    CFileDialog fileDlg (TRUE, "*.*", "*.bmp",
      OFN_FILEMUSTEXIST| OFN_HIDEREADONLY, "*.bmp", this);
   
   // Display the file dialog. When user clicks OK, fileDlg.DoModal() 
   // returns IDOK.
   if( fileDlg.DoModal ()==IDOK )
   {
    
	 CString pathName = fileDlg.GetPathName();
   
	int w = 512, h = 512;
	//Dynamischen Bildspeicher erzeugen (Feld mit Zeigern und Feld mit Zeigern auf 
	unsigned char* pBuffer = new UCHAR[w*h];  //dem Anfang jeder Zeile.
	unsigned char** ppBild = new UCHAR*[h];
	for(int i = 0; i < h; i++) ppBild[i] = pBuffer + i* w; 


	unsigned char header[sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)];

	BITMAPINFOHEADER *pBMIH = (BITMAPINFOHEADER*)header;
	RGBQUAD *pColors = (RGBQUAD*)((char*)header+sizeof(BITMAPINFOHEADER));
	
	pBMIH->biSize =   sizeof(BITMAPINFOHEADER); // Anzahl der Bytes der BITMAPINFOHEADER Struktur
	pBMIH->biWidth =  512;						// Breite der Bitmap
	pBMIH->biHeight = -512;						// Höhe der Bitmap
	pBMIH->biPlanes = 1;						// Anzahl der Ebenen <=> muss 1 sein!
	pBMIH->biBitCount = 8;						// Anzahl der Bits pro Pixel (0,1,4,8,16,
	pBMIH->biClrUsed  =  255;
	pBMIH->biCompression = BI_RGB;				// Art der Komprimierung
	pBMIH->biSizeImage	= 0;					// Für BI_RGB erlaubt
	pBMIH->biXPelsPerMeter = 0;					// Für die blosse Anzeige nicht wichtig
	pBMIH->biYPelsPerMeter = 0;					//                     "
	pBMIH->biClrUsed = 0;						// Volle Auflösung = 256 Einträge in die Farbtabelle bei 8-Bit pro Pixel

	//Farbtabelle füllen	
	for(i = 0; i < 256; i++) {
		pColors[i].rgbBlue = i;
		pColors[i].rgbRed = i;
		pColors[i].rgbGreen = i;
		pColors[i].rgbReserved = 0;
	}


	std::ifstream in(pathName,ios::binary);
	in.read((char*)pBuffer,w*h);
	
	CClientDC dc(this);

	CRect r;
	GetClientRect(&r);
	dc.SetStretchBltMode(COLORONCOLOR);

//  StretchDIBits(dc.m_hDC,0,0,r.Width(),r.Height(),0,0,w,h,pBuffer,(BITMAPINFO*)pBMIH,DIB_RGB_COLORS,SRCCOPY);

	SetDIBitsToDevice(dc.m_hDC,0,0,w,h,0,0,0,h,pBuffer,(BITMAPINFO*)pBMIH,DIB_RGB_COLORS);

     
      //Change the window's title to the opened file's title.
      CString fileName = fileDlg.GetFileTitle ();
   
      SetWindowText(fileName);
   }



}


was ich haupsächlich möchte ist, dass ich Width und Height auslesen kann und dann mein Dynamisches Array entsprechend der beiden Größen aufziehn kann.
Und wie ich das Bild so ausrichten kann, dass es nicht mehr auf dem Kopf liegt.
Ich weiß zwar, dass es "pBMIH->biHeight = -512;" daran liegt, aber weiß auch nciht, wie ich ihm das sagen soll...
Hoffe jemand versteht (trotz meiner verwirrenden ausdrucksweise) was ich meine... ;)

Danke schonmal
mfg
doggy
 
Hallo Bl@ckD0G,

hier findest Du eine Methode um ein Bild direkt einzulesen:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdicpp/GDIPlus/GDIPlusReference/Classes/ImageClass/ImageMethods/FromFile_75filename_useEmbeddedColorManagement.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdicpp/GDIPlus/UsingGDIPlus/UsingImagesBitmapsandMetafiles/LoadingandDisplayingBitmaps.asp

Den Bitmapinfoheader brauchst du meines Wissens nach nicht selber zu erstellen der ist im File enthalten. Siehe die Strukturdefinition von BitmapInfoHeader. Die Daten des Files sind direkt danach im Anhang. D.h. du musst eigentlich nur die Pointer auf die richtigen Stellen setzen.

Das das Bild gespiegelt ist, liegt an der negativen biHeight.

Vor allem legt dein Code dich auf 8 Bit Bitmaps fest. Damit wirst Du keine 32 Bit Bitmap laden können.

MfG

Arnd
 
Zuletzt bearbeitet:
Danke ist zwar eigentlich richtig, aber im prinzip möchte ich gerne meine routinen verwenden und die Frage war eigentlich eher :


was ich haupsächlich möchte ist, dass ich Width und Height auslesen kann und dann mein Dynamisches Array entsprechend der beiden Größen aufziehn kann.

D.h. wie ich Infos aus dem BMPHeader gescheit lesen kann.
 
Auf dieser Seite findest du genau beschrieben, wie ein BMP Bild aufgebaut ist: http://www.wotsit.org/search.asp?s=graphics

Nach der Lektüre solltest du in der Lage sein eine solche Datei auzulesen und auch selbst zu schreiben :).
 
- Lade das File in den Speicher entweder ganz oder nur sizeof BITMAPINFOHEADER.
- Caste einen BITMAPINFOHEADER* auf den Anfang der eingelesenen Daten
- Lese Höhe und Breite aus.
- Fertig

Eventuell musst Du ein paar Byte am Anfang (struct BITMAPFILEHEADER) überspringen, falls im Dateiheader noch eine Kennung drin ist. Im Debugger sieht man das aber schnell. Schliesslich weisst Du wie gross die Bitmap ist und damit welcher Wert an welcher Stelle stehen muss.

MfG

Arnd

PS: Schau dir mal LoadImage mit dem Parameter LR_LOADFROMFILE an. Das macht das selbe nur ohne GDI+.
 
Zuletzt bearbeitet:
ok danke für die Tips werd ich mir mal anschaun bzw. ausprobieren!

EDIT: Seit wann ist denn das Karmasystem weg?
 

Ähnliche Themen

Zurück
Oben