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.pngDer 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.
-
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?