Windows Bitmap



  • Hey,

    ich schreibe grad einen BMP Viewer und das seltsame ist, mit manchen Bildern funktioniert es und mit den meisten aber nicht. Obwohl alle 200x200px groß sind, 24bit haben und nicht komprimiert sind.

    Jetzt ist mir in meiner Logdatei aufgefallen:

    Opening 'image.bmp'...
    Filesize: 120056 bytes
    
    Fileheader (14 bytes)
    --------------------
    bfType: 19778
    bfSize: 120056
    bfReserved1: 0
    bfReserved2: 0
    bfOffBits: 54
    
    Infoheader (40 bytes)
    --------------------
    biSize: 40
    biWidth: 200
    biHeight: 200
    biPlanes: 1
    biBitCount: 24
    biCompression: 0
    biSizeImage: 120002
    biXPelsPerMeter: 2834
    biYPelsPerMeter: 2834
    biClrUsed: 0
    biClrImportant: 0
    
    bottom_up = TRUE
    
    Imagedata (120002 bytes)
    
    File read successfully!
    

    200*200pixel * 24bit/pixel = 960000 bit = 120000 byte

    Die Log sagt aber, dass die Imagedata 120002 byte beträgt. Im Header steht es auch so.
    Jetzt frage ich mich: Wo kommen diese überschüssigen 2 Byte her??

    In Bitmaps beginnt die Imagedata bei Offset 54. Und die Pixel werden einfach aneinander gereiht in 3er Tuppeln nach dem Schema(B - G - R). Ein Pixel ist 3 Byte groß.

    Windows, Photosphop, Paint... alle können das BMP ohne Probleme öffnen.

    Das genannte BMP: http://bloody-blades.de/images/bmp/image.bmp
    So siehts aus in meinem Viewer: http://bloody-blades.de/images/bmp/viewer.png

    Der untere Teil stimmt vollkommen überein mit dem Bild, aber dann wird es einfach abgeschnitten. Weils ein Bottom-Up Bild ist, stehen die Bilddaten, die angezeigt werden, am Anfang der Datei. Daraus schließe ich, dass er anfangs wunderbar auslesen kann, aber dann kommt er mit irgendwas nicht mehr klar...

    Ich hab leider das Bild nicht mehr, mit dem es geklappt hat.

    Infos: http://de.wikipedia.org/wiki/Windows_bitmap



  • Einlesen tue ich so:

    bool Bitmap::Load(std::string file)
    {
    	ofstream log(string(file + ".txt").c_str(), ios::out);
    
    	ifstream bmp(file.c_str(), ios::in || ios::binary);
    	if (bmp.fail())
    	{
    		log << "ERROR: Failed to open '" << file << "'" << endl;
    		return false;
    	}
    	else
    		log << "Opening '" << file << "'..." << endl;
    
    	bmp.seekg(0, ios::end);
    	long filesize = bmp.tellg();
    	bmp.seekg(0, ios::beg);
    
    	log << "Filesize: " << filesize << " bytes" << endl << endl;
    
    	char *buffer = new char[filesize];
    
    	bmp.read(buffer, filesize);
    	bmp.close();
    
    	char *pointer =  buffer;
    
    	BITMAPFILEHEADER *fileheader = (BITMAPFILEHEADER*) pointer;
    
    	log << "Fileheader (" << sizeof(BITMAPFILEHEADER) << " bytes)" << endl;
    	log << "--------------------" << endl;
    	log << "bfType: " << fileheader->bfType << endl;
    	log << "bfSize: " << fileheader->bfSize << endl;
    	log << "bfReserved1: " << fileheader->bfReserved1 << endl;
    	log << "bfReserved2: " << fileheader->bfReserved2 << endl;
    	log << "bfOffBits: " << fileheader->bfOffBits << endl;
    	log << endl;
    
    	if (fileheader->bfType != 19778)
    	{
    		log << "ERROR: No valid bmp file!" << endl;
    		return false;
    	}
    
    	pointer += sizeof(BITMAPFILEHEADER); // zum Infoheader springen
    
    	BITMAPINFOHEADER *infoheader = (BITMAPINFOHEADER*) pointer;
    
    	log << "Infoheader (" << sizeof(BITMAPINFOHEADER) << " bytes)" << endl;
    	log << "--------------------" << endl;
    	log << "biSize: " << infoheader->biSize << endl;
    	log << "biWidth: " << infoheader->biWidth << endl;
    	log << "biHeight: " << infoheader->biHeight << endl;
    	log << "biPlanes: " << infoheader->biPlanes << endl;
    	log << "biBitCount: " << infoheader->biBitCount << endl;
    	log << "biCompression: " << infoheader->biCompression << endl;
    	log << "biSizeImage: " << infoheader->biSizeImage << endl;
    	log << "biXPelsPerMeter: " << infoheader->biXPelsPerMeter << endl;
    	log << "biYPelsPerMeter: " << infoheader->biYPelsPerMeter << endl;
    	log << "biClrUsed: " << infoheader->biClrUsed << endl;
    	log << "biClrImportant: " << infoheader->biClrImportant << endl;
    	log << endl;
    
    	if (infoheader->biBitCount != 24)
    	{
    		log << "ERROR: Only 24 bits supported!" << endl;
    		return false;
    	}
    
    	width = infoheader->biWidth;
    	height = infoheader->biHeight;
    
    	if (height < 0)
    	{
    		height *= -1;
    		bottom_up = false;
    		log << "bottom_up = FALSE" << endl << endl;
    	}
    	else
    	{
    		bottom_up = true;
    		log << "bottom_up = TRUE" << endl << endl;
    	}
    
    	log << "Imagedata (" << infoheader->biSizeImage << " bytes)" << endl;
    	log << endl;
    
    	imagedata = new Color[width*height];
    
    	pointer += sizeof(BITMAPINFOHEADER); // zu Bildinformationen springen
    
    	for (int i = 0; i < width*height; i++)
    	{
    		RGBTRIPLE *color = (RGBTRIPLE*)pointer;
    
    		imagedata[i].r = int(color->rgbtRed);
    		imagedata[i].g = int(color->rgbtGreen);
    		imagedata[i].b = int(color->rgbtBlue);
    
    		pointer += sizeof(RGBTRIPLE);
    	}
    
    	buffer = NULL;
    	fileheader = NULL;
    	infoheader = NULL;
    	pointer = NULL;
    
    	log << "File read successfully!" << endl;
    	log << endl;
    
    	log.close();
    
    	return true;
    }
    


  • Okaaaaaaaaay ich verstehs nicht.
    Jetzt geht's auf einmal wieder. Mit dem _selben_ Bild, das vorher nicht ging.

    Könnte es vielleicht an meiner kaputten Festplatte liegen?


Anmelden zum Antworten