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!!");
}
11
  • 3
    bitmap[2] = 454; that value does not fit into a single char. Commented May 31, 2015 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? Commented May 31, 2015 at 16:19
  • If you are using an array not a struct it should be unsigned char bitmap[1000]; Commented May 31, 2015 at 16:40
  • 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. Commented May 31, 2015 at 17:11
  • 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 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! Commented May 31, 2015 at 17:41

2 Answers 2

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!!");
}
Sign up to request clarification or add additional context in comments.

Comments

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 Comment

Hi, Welcome to stackoverflow. It seems that your answer doesn't point out what went wrong with the code. Please make sure to read stackoverflow.com/help/how-to-answer before proceeding.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.