Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a BMP file (bitmap) in C

Tags:

c

bitmap

bmp

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!

like image 896
Devos50 Avatar asked Jun 12 '12 21:06

Devos50


People also ask

How do I create a BMP file in C++?

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.

How is a bitmap BMP file structured?

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.

What is new bitmap image BMP?

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.


1 Answers

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.

like image 199
Gareth McCaughan Avatar answered Oct 13 '22 01:10

Gareth McCaughan