So I'm trying to export a .bmp file in C++ code, and I have it working except for one major thing: line padding. I'm not 100% sure on how line padding works, but I know I need it. My algorithm works except for the padding, I manually added padding in a hex editor to my exported image and it worked. But how do I add padding? Here is what I have:
//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[1000000];
unsigned char bmpPad[3] = {0, 0, 0};
//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);
//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;
pixelArray[counter] = pixelColour[i][j].green;
pixelArray[counter] = pixelColour[i][j].blue;
counter++;
}
}
//Open it
ofstream fileWorking(fileName);
//Write the sections
fileWorking.write((const char*)generalHeader, 14);
fileWorking.write((const char*)DIBHeader, 40);
fileWorking.write((const char*)pixelArray, 3 * width * height);
//NO MEMORY LEAKS 4 ME
fileWorking.close();
pixelColour is of struct data type with the 3 colours, all type unsigned char. Any help is greatly appreciated!
The final part of the BMP file is the image data. The data is stored row by row with padding on the end of each row. The padding ensures the image rows are multiples of four.
BMP files are uncompressed. If you want to compress a BMP file, you must do it manually.
BMP images are generally uncompressed or compressed with a lossless compression method. The files can store two-dimensional digital images with both monochrome and color. Various Color Depths, alpha channels, color profiles and optional data compression are supported in this format.
BMP files are sometimes known as “true images” because they render each individual pixel within the file. They don't compress automatically. This makes them large — a collection of BMP files will rapidly consume lots of memory and space.
In your case, each row must be a multiple of 4 bytes (32 bits).
int pad = 0; // Set pad byte count per row to zero by default.
// Each row needs to be a multiple of 4 bytes.
if ((width * 3) % 4 != 0) pad = 4 - ((width * 3) % 4); // 4 - remainder(width * 3 / 4).
Padding values can contain pretty much anything, but it is best to set them to 0. When you reach the end of writing each row, just write an additional pad
number of zeroes (bytes) before writing the next row.
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; // Need to advance counter.
pixelArray[counter++] = pixelColour[i][j].green;
pixelArray[counter++] = pixelColour[i][j].blue;
}
for (int padVal = 0; padVal < pad; padVal++) pixelArray[counter++] = 0; // Pad.
}
Finally, you need to write a larger file size:
fileWorking.write((const char*) pixelArray, (3 * width + pad) * height);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With