0

So, as the title states, I'm having trouble exporting a .bmp (24-bit bmp) with C++. I am doing it as a school project type thing, and I need some help. To learn how .BMPs work I looked at the wikipedia page, and I got some help from here, but I still can't figure it out. Here is what I have:

//Export the map as a .bmp
void PixelMap::exportMap(const char* fileName)
{
    //Size of the file in bytes
    int fileSize = 54 + (3 * width * height);

    //The sections of the file
    unsigned char generalHeader[14] = {'B','M',0,0, 0,0,0,0, 0,0,54,0, 0,0};
    unsigned char DIBHeader[40]     = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0,24,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
    unsigned char pixelArray[]      = "";

    //Set the binary portion of the generalHeader, mainly just file size
    generalHeader[2] = (unsigned char)(fileSize);
    generalHeader[3] = (unsigned char)(fileSize << 8);
    generalHeader[4] = (unsigned char)(fileSize << 16);
    generalHeader[5] = (unsigned char)(fileSize << 24);

    //The binary variable portion of the DIB header
    DIBHeader[4]  = (unsigned char)(width);
    DIBHeader[5]  = (unsigned char)(width << 8);
    DIBHeader[6]  = (unsigned char)(width << 16);
    DIBHeader[7]  = (unsigned char)(width << 24);
    DIBHeader[8]  = (unsigned char)(height);
    DIBHeader[9]  = (unsigned char)(height << 8);
    DIBHeader[10] = (unsigned char)(height << 16);
    DIBHeader[11] = (unsigned char)(height << 24);
    int picSize = 3 * width * height;
    DIBHeader[20] = (unsigned char)(picSize);
    DIBHeader[21] = (unsigned char)(picSize << 8);
    DIBHeader[22] = (unsigned char)(picSize << 16);
    DIBHeader[23] = (unsigned char)(picSize << 24);

    //Loop through all width and height places to add all pixels
    int counter = 0;
    for(short j = height; j >= 0; j--)
    {
        for(short i = 0; i < width; i++)
        {
            //Add all 3 RGB values
            pixelArray[counter] = pixelColour[i, j].red;
            counter++;
            pixelArray[counter] = pixelColour[i, j].green;
            counter++;
            pixelArray[counter] = pixelColour[i, j].blue;
            counter++;
        }
    }

    //Open it
    ofstream fileWorking(fileName);

    //Write the sections
    fileWorking << generalHeader;
    fileWorking << DIBHeader;
    fileWorking << pixelArray;

    //NO MEMORY LEAKS 4 ME
    fileWorking.close();
}

This is part of a class called 'PixelMap,' basically a frame buffer or surface. The PixelMap has the variables 'width,' 'height,' and the struct array 'pixelColour.' (The struct containing 3 chars called 'red' 'green' and 'blue') If you would like to see the class, here it is. (It's just a skeleton, trying to get the .bmp down first)

//This is a pixel map, mainly for exporting BMPs
class PixelMap
{
public:

    //The standard pixel variables
    int width;
    int height;
    Colour pixelColour[];

    //The constructor will set said variables
    PixelMap(int Width, int Height);

    //Manipulate pixels
    void setPixel(int X, int Y, char r, char g, char b);

    //Export the map
    void exportMap(const char* fileName);
};

(Colour is the struct)

So my problem here is that when I try to run this, I get this: Error So pixelArray, the array of colours to be exported gets corrupted. I assume this has to do with not being properly given a size, but I try to assign it's proper value (3 * width * height (3 being RGB)) but it says that it needs to be a constant value.

Any help with this issue is greatly appreciated!

Community
  • 1
  • 1
null
  • 548
  • 2
  • 6
  • 17

1 Answers1

1

Instead of

unsigned char pixelArray[]      = "";

you could use:

std::vector<unsigned char> pixelArray(3*width*height,0);

This declares a vector with 3*width*height elements, initialized to 0. You can access the elements using the same syntax you've used for the array version (except, as pointed out in comments, you'll have to take care to write the binary values correctly to the output file).

Jim Lewis
  • 43,505
  • 7
  • 82
  • 96
  • So I took what you suggested, and I need to research vectors, but how do I sort out the fileWorking << issue? I think I'm supposed to use fileWorking.write but how can I convert unsigned char[] to const char* for the first argument? (P.S. thanks for the help) – null Apr 03 '15 at 17:37
  • @Paolo: That's probably better as a separate question. – Jim Lewis Apr 03 '15 at 17:48