0

This is a follow up question from here, Link

I read and copy pasted the code from the link to Code::Blocks but with a little change,

Now I want to create a 20x20 black image

So I edited the code but I am unable to open the image on Win7, it says 'Windows Photo Viewer can't open this Image'.

Can anyone please advice me what is wrong with the code ??

My code:-

#include<stdio.h>
 unsigned char bitmap[1000];


void BMPmake()
{
    int i;
    // -- FILE HEADER -- //

    // bitmap signature
    bitmap[0] = 'B';
    bitmap[1] = 'M';

    // file size
    bitmap[2] = 0xc6; // 40 + 14 + 400
    bitmap[3] = 0x01;
    bitmap[4] = 0;
    bitmap[5] = 0;

    // reserved field (in hex. 00 00 00 00)
    for( i = 6; i < 10; i++) bitmap[i] = 0;

    // offset of pixel data inside the image
    //thats is 54 or d8 the difference between the starting and the position where data actually starts.
    bitmap[10]=0xd8;
    for( i = 11; i < 14; i++) bitmap[i] = 0;


    // -- BITMAP HEADER -- //

    // header size
    bitmap[14] = 40;
    for( i = 15; i < 18; i++) bitmap[i] = 0;

    // width of the image
    bitmap[18] = 20;
    for( i = 19; i < 22; i++) bitmap[i] = 0;

    // height of the image
    bitmap[22] = 20;
    for( i = 23; i < 26; i++) bitmap[i] = 0;

    // no of color planes, must be 1
    bitmap[26] = 1;
    bitmap[27] = 0;

    // number of bits per pixel
    bitmap[28] = 8; // 1 byte
    bitmap[29] = 0;

    // compression method (no compression here)
    for( i = 30; i < 34; i++) bitmap[i] = 0;

    // size of pixel data
    bitmap[34] = 0x90; // 400 bytes => 400 pixels ,,,, 20x20x1
    bitmap[35] = 0x01;
    bitmap[36] = 0;
    bitmap[37] = 0;

    // horizontal resolution of the image - pixels per meter (2835)
    bitmap[38] = 0;
    bitmap[39] = 0;
    bitmap[40] = 0;
    bitmap[41] = 0;

    // vertical resolution of the image - pixels per meter (2835)
    bitmap[42] = 0;
    bitmap[43] = 0;
    bitmap[44] = 0;
    bitmap[45] = 0;

    // color palette information here 256
    bitmap[46]=0xff;
    bitmap[47]=1;
    for( i = 48; i < 50; i++) bitmap[i] = 0;

    // number of important colors
    for( i = 50; i < 54; i++) bitmap[i] = 0;

    // -- PIXEL DATA -- //
    for( i = 54; i < 454; i++) bitmap[i] = 0xff;
}

void BMPwrite()
{
    FILE *file;
    int i;
    file = fopen("b.bmp", "wb+");
    for( i = 0; i < 454; i++)
    {
        fputc(bitmap[i], file);
    }
    fclose(file);
}
void main()
{

    BMPmake();
    BMPwrite();
    printf("Done!!");
}
Community
  • 1
  • 1
Mohit
  • 1,045
  • 4
  • 18
  • 45
  • 3
    `bitmap[2] = 454;` that value does not fit into a single char. – wildplasser May 31 '15 at 16:18
  • 1
    I've got a suggestion: what about creating a bitmap of size `20x20` with black background , then opening both this bitmap and your output in some hex editor and comparing them to to find possibly error-causing differences? – user35443 May 31 '15 at 16:19
  • If you are using an array not a struct it should be *`unsigned`* `char bitmap[1000];` – Weather Vane May 31 '15 at 16:40
  • @wildplasser silly mistake, did the following changes `bitmap[2] = 0x6c; bitmap[3] = 1;` still same error – Mohit May 31 '15 at 16:43
  • @user35443 nice suggestion but a lengthy one, will try it if unable to find solution here. Thanks. – Mohit May 31 '15 at 16:44
  • @Mohit re edit (from Wildplasser's comment) 454 is not `0x16C` it is `0x1C6` – Weather Vane May 31 '15 at 16:57
  • @WeatherVane yeah, thanks for pointing it out...just corrected it, still not showing :( – Mohit May 31 '15 at 17:04
  • 1
    Offset 46 is the number of palette entries - 0xFF here, yet you do not provide a 256-entry palette table. Worse it's a 4 byte field and you have `0x1FF`. – Weather Vane May 31 '15 at 17:11
  • @WeatherVane That, I didn't knew about. Can you help me how to provide it and where? – Mohit May 31 '15 at 17:19
  • Also: the value should probably be stored MSB first / LSB last; big-endian. Check the docs! – wildplasser May 31 '15 at 17:29
  • 1
    I am tempted to rewrite the code but since everything is "hard-coded" I will leave that to you. Note that the offset of the image data will need changing.There are lots of resources out there, for example http://en.wikipedia.org/wiki/BMP_file_format. I also recommend @user35443's advice, if that's not too much trouble... it's a few minutes work! – Weather Vane May 31 '15 at 17:41

2 Answers2

1

With thanks to Weather Vane, wildplasser and user35443 I was able to solve my problem.

The main problem was that I didn't implement the color table which is necessary in bitmap when no of bits/pixel<=8, so by comparing a original bitmap with mine I was able to find the format of 8bit Greyscale color table, I generated it using the following code:

unsigned char temp=0;
int end_color=54+4*noColor;
//where noColor is 256 as 2^8 here where 8 is no of bits/pixel.
for (i=54;i<end_color;i+=4)
    {
        bitmap[i]=temp;
        bitmap[i+1]=temp;
        bitmap[i+2]=temp;
        bitmap[i+3]=0;
        temp++;
    }

Overall Code:-

#include<stdio.h>
   unsigned char bitmap[1300];


void BMPmake()
{
    int i,noColor=256,end_color=54+4*noColor;
    static unsigned char temp=0;
    // -- FILE HEADER -- //

    // bitmap signature
    bitmap[0] = 'B';
    bitmap[1] = 'M';

    // file size
    bitmap[2] = 0xc6; // 40 + 14 + 256*4+400
    bitmap[3] = 0x05;
    bitmap[4] = 0;
    bitmap[5] = 0;

    // reserved field (in hex. 00 00 00 00)
    for( i = 6; i < 10; i++) bitmap[i] = 0;

    // offset of pixel data inside the image
    //The offset, i.e. starting address, of the byte where the bitmap image data (pixel array) can be found.
    //here 1078
    bitmap[10]=0x36;
    bitmap[11]=0x04;
    for( i = 12; i < 14; i++) bitmap[i] = 0;


    // -- BITMAP HEADER -- //

    // header size
    bitmap[14] = 40;
    for( i = 15; i < 18; i++) bitmap[i] = 0;

    // width of the image
    bitmap[18] = 20;
    for( i = 19; i < 22; i++) bitmap[i] = 0;

    // height of the image
    bitmap[22] = 20;
    for( i = 23; i < 26; i++) bitmap[i] = 0;

    // no of color planes, must be 1
    bitmap[26] = 1;
    bitmap[27] = 0;

    // number of bits per pixel
    bitmap[28] = 8; // 1 byte
    bitmap[29] = 0;

    // compression method (no compression here)
    for( i = 30; i < 34; i++) bitmap[i] = 0;

    // size of pixel data
    bitmap[34] = 0x90; // 400 bytes => 400 pixels ,,,, 20x20x1
    bitmap[35] = 0x01;//0x190
    bitmap[36] = 0;
    bitmap[37] = 0;

    // horizontal resolution of the image - pixels per meter (2835)
    bitmap[38] = 0;
    bitmap[39] = 0;
    bitmap[40] = 0;
    bitmap[41] = 0;

    // vertical resolution of the image - pixels per meter (2835)
    bitmap[42] = 0;
    bitmap[43] = 0;
    bitmap[44] = 0;
    bitmap[45] = 0;

    // color palette information here 256
    bitmap[46]=0;
    bitmap[47]=1;
    for( i = 48; i < 50; i++) bitmap[i] = 0;

    // number of important colors
    // if 0 then all colors are important
    for( i = 50; i < 54; i++) bitmap[i] = 0;

    //Color Palette
    //for less then or equal to 8 bit BMP Image we have to create a 4*noofcolor size color palette which is nothing but
    //[BLUE][GREEN][RED][ZERO] values
    //for 8 bit we have the following code
    for (i=54;i<end_color;i+=4)
    {
        bitmap[i]=temp;
        bitmap[i+1]=temp;
        bitmap[i+2]=temp;
        bitmap[i+3]=0;
        temp++;
    }

    // -- PIXEL DATA -- //
    for( i = end_color; i < end_color+400; i++) bitmap[i] = 0xff;
}

void BMPwrite()
{
    FILE *file;
    int i;

    //use wb+ when writing to binary file .i.e. in binary form whereas w+ for txt file.
    file = fopen("b.bmp", "wb+");
    for( i = 0; i < 1478; i++)
    {
        fputc(bitmap[i], file);
    }
    fclose(file);
}
void main()
{

    BMPmake();
    BMPwrite();
    printf("Done!!");
}
Mohit
  • 1,045
  • 4
  • 18
  • 45
0

0xff is 255, right then it points to index of palette 255 which holds the value of rgb all 255 then it should display white right how come u r getting black

  • 1
    Hi, Welcome to stackoverflow. It seems that your answer doesn't point out what went wrong with the code. Please make sure to read https://stackoverflow.com/help/how-to-answer before proceeding. – Waqar Jun 04 '20 at 20:32