I'm trying to make a bitmap in C, just from code. I'm currently trying to make a very easy .bmp image, with a height of 1px and a width of 4 pixels, with all white pixels. I have read the format description and tried to apply it. This resulted in the following code:
char bitmap[1000];
void BMPmake()
{
// -- FILE HEADER -- //
// bitmap signature
bitmap[0] = 'B';
bitmap[1] = 'M';
// file size
bitmap[2] = 66; // 40 + 14 + 12
bitmap[3] = 0;
bitmap[4] = 0;
bitmap[5] = 0;
// reserved field (in hex. 00 00 00 00)
for(int i = 6; i < 10; i++) bitmap[i] = 0;
// offset of pixel data inside the image
for(int i = 10; i < 14; i++) bitmap[i] = 0;
// -- BITMAP HEADER -- //
// header size
bitmap[14] = 40;
for(int i = 15; i < 18; i++) bitmap[i] = 0;
// width of the image
bitmap[18] = 4;
for(int i = 19; i < 22; i++) bitmap[i] = 0;
// height of the image
bitmap[22] = 1;
for(int i = 23; i < 26; i++) bitmap[i] = 0;
// reserved field
bitmap[26] = 1;
bitmap[27] = 0;
// number of bits per pixel
bitmap[28] = 24; // 3 byte
bitmap[29] = 0;
// compression method (no compression here)
for(int i = 30; i < 34; i++) bitmap[i] = 0;
// size of pixel data
bitmap[34] = 12; // 12 bits => 4 pixels
bitmap[35] = 0;
bitmap[36] = 0;
bitmap[37] = 0;
// horizontal resolution of the image - pixels per meter (2835)
bitmap[38] = 0;
bitmap[39] = 0;
bitmap[40] = 0b00110000;
bitmap[41] = 0b10110001;
// vertical resolution of the image - pixels per meter (2835)
bitmap[42] = 0;
bitmap[43] = 0;
bitmap[44] = 0b00110000;
bitmap[45] = 0b10110001;
// color pallette information
for(int i = 46; i < 50; i++) bitmap[i] = 0;
// number of important colors
for(int i = 50; i < 54; i++) bitmap[i] = 0;
// -- PIXEL DATA -- //
for(int i = 54; i < 66; i++) bitmap[i] = 0;
}
void BMPwrite()
{
FILE *file;
file = fopen("bitmap.bmp", "w+");
for(int i = 0; i < 66; i++)
{
fputc(bitmap[i], file);
}
fclose(file);
}
When I try to open this image, it says that the image is damaged. Am I missing something here?
I also noticed that the encoding of the .bmp integers is little endian. I thought that this mean that I have to reverse the order of the bytes. For example, 256 in four bytes is: 00000000 00000000 00000001 00000000, and I think in little endian this would be: 00000000 00000001 00000000 00000000
Can anyone give me a hand here? Am I using a right approach? Any help would be appreciated!
Thanks in advance!
Here is the code for writing the image to disk: 1 struct BMP { 2 // ... 3 4 void write(const char *fname) { 5 std::ofstream of{ fname, std::ios_base::binary }; 6 if (of) { 7 if (bmp_info_header. bit_count == 32) { 8 write_headers_and_data(of); 9 } 10 else if (bmp_info_header.
The bitmap image file consists of fixed-size structures (headers) as well as variable-sized structures appearing in a predetermined sequence. Many different versions of some of these structures can appear in the file, due to the long evolution of this file format.
BMP is a simple raster graphics image file format designed to store bitmap digital images independently of a display device, originally and primarily on Microsoft Windows and OS/2 operating systems.
Your pixel offset (bytes 10..13) is zero, but the pixel data don't actually start at the beginning of the file, they start at byte 54.
Also:
Your comment on byte 34 says "bits" but means "bytes", but of course that doesn't matter.
Your horizontal and vertical resolutions have the wrong byte order, but I very much doubt that that matters.
If I were doing this I'd define structs for the header data (indeed, if you're on Windows, Microsoft have already done this) and use a macro or something for putting bytes into the right order portably.
Whether you "have to reverse the order of the bytes" depends on the endianity of the processor you're using. Writing separate bytes separately, as you're doing, is an effective way to avoid having to worry about this.
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