c++bitmapbmpofstream

C++ How to create a bitmap file


I am trying to figure out how to create a bitmap file in C++ VS. Currently I have taken in the file name and adding the ".bmp" extension to create the file. I want to know how I could change the pixels of the file by making it into different colors or patterns (ie. like a checkerboard) This is my function that I have and I believe that I have to send 3 different Bytes at a time in order to establish the color of the pixel.

void makeCheckerboardBMP(string fileName, int squaresize, int n) {
    ofstream ofs;
    ofs.open(fileName + ".bmp");
    writeHeader(ofs, n, n);

    for(int row = 0; row < n; row++) {
        for(int col = 0; col < n; col++) {

            if(col % 2 == 0) {
                ofs << 0;
                ofs << 0;
                ofs << 0;
            } else {
                ofs << 255;
                ofs << 255;
                ofs << 255;
            }
        }
    }
}

void writeHeader(ostream& out, int width, int height){
    if (width % 4 != 0) {
        cerr << "ERROR: There is a windows-imposed requirement on BMP that the width be a          
multiple of 4.\n";
        cerr << "Your width does not meet this requirement, hence this will fail.  You can fix     
this\n";
        cerr << "by increasing the width to a multiple of 4." << endl;
        exit(1);
    }

    BITMAPFILEHEADER tWBFH;
    tWBFH.bfType = 0x4d42;
    tWBFH.bfSize = 14 + 40 + (width*height*3);
    tWBFH.bfReserved1 = 0;
    tWBFH.bfReserved2 = 0;
    tWBFH.bfOffBits = 14 + 40;

    BITMAPINFOHEADER tW2BH;
    memset(&tW2BH,0,40);
    tW2BH.biSize = 40;
    tW2BH.biWidth = width;
    tW2BH.biHeight = height;
    tW2BH.biPlanes = 1;
    tW2BH.biBitCount = 24;
    tW2BH.biCompression = 0;

    out.write((char*)(&tWBFH),14);
    out.write((char*)(&tW2BH),40);
}

Solution

  • Given your writeHeader is properly implemented this is almost correct. You need to fix 2 issues though:

    1. You are writing one int per color channel. This should be one byte instead. You need to cast the literals to unsigned char.
    2. Scanlines in bitmaps need to be DWORD-aligned. After your inner loop over col you need to write additional bytes to account for this, unless the size in bytes of the row is a multiple of four.