13 Replies - 831 Views - Last Post: 13 February 2021 - 06:04 AM Rate Topic: -----

#1 wolfrose   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 72
  • Joined: 20-January 16

Converting bmp files to c array code problem

Posted 06 February 2021 - 08:51 PM

Hi,

I found a code on a forum to convert a bmp monochrome to C array, I want to use the array for microcontroller graphic LCD 128x64. The output array is 1024 bytes. Color depth is 1 as it's black and white only.

At first I got two problems:
1. Output is flipped upside down
2. The image get misplaced on the LCD


This is the code:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

struct BitMap{
    short     Type;
    long      Size;
    short     Reserve1;
    short     Reserve2;
    long      OffBits;
    long      biSize;
    long      biWidth;
    long      biHeight;
    short     biPlanes;
    short     biBitCount;
    long      biCompression;
    long      biSizeImage;
    long      biXPelsPerMeter;
    long      biYPelsPerMeter;
    long      biClrUsed;
    long      biClrImportant;
} Header;

short arr[1024];

int main(void){
    short x= 0 ,y = 0 , p = 0;
    short pixelValue = 0 ;
    int   myPalette[2];

    FILE *BMPFile = fopen ("bmp.bmp", "r");
    if (BMPFile == NULL) return -1;

    fread(&Header.Type,               sizeof(Header.Type), 1, BMPFile);
    fread(&Header.Size,               sizeof(Header.Size), 1, BMPFile);
//    fread(&Header.Reserve1,           sizeof(Header.Reserve1) , 1, BMPFile);
    fread(&Header.Reserve2,           sizeof(Header.Reserve2) , 1, BMPFile);
    fread(&Header.OffBits,            sizeof(Header.OffBits), 1, BMPFile);
    fread(&Header.biSize,             sizeof(Header.biSize), 1, BMPFile);
    fread(&Header.biWidth,            sizeof(Header.biWidth), 1, BMPFile);
    fread(&Header.biHeight,           sizeof(Header.biHeight) , 1, BMPFile);

    fread(&Header.biPlanes,           sizeof(Header.biClrUsed),  1, BMPFile);
    fread(&Header.biBitCount,         sizeof(Header.biBitCount), 1, BMPFile);
    fread(&Header.biCompression,      sizeof(Header.biCompression), 1, BMPFile);
    fread(&Header.biSizeImage,        sizeof(Header.biSizeImage), 1, BMPFile);
    fread(&Header.biXPelsPerMeter,    sizeof(Header.biXPelsPerMeter), 1, BMPFile);
    fread(&Header.biYPelsPerMeter,    sizeof(Header.biYPelsPerMeter), 1, BMPFile);

    fread(&Header.biClrUsed,          sizeof(Header.biClrUsed), 1, BMPFile);
    fread(&Header.biClrImportant,     sizeof(Header.biClrImportant),  1, BMPFile);
    fread(&myPalette[0],              4,  2, BMPFile);

    printf("\nType:%hd  and Type in  %x\n", Header.Type,Header.Type);
    printf("Size:%ld\n", Header.Size);
    printf("Width:%ld\n", Header.biWidth);
    printf("Height:%ld\n", Header.biHeight);
    printf("biPlanes:%hd\n", Header.biPlanes);
    printf("biBitCount:%hd\n", Header.biBitCount);
    printf("biCompression:%ld\n", Header.biCompression);
    printf("biSizeImage:%ld\n", Header.biSizeImage);
    printf("biXPelsPerMeter:%ld\n", Header.biXPelsPerMeter);
    printf("biYPelsPerMeter:%ld\n", Header.biYPelsPerMeter);
    printf("biClrUsed:%ld\n", Header.biClrUsed);
    printf("biClrImportant:%ld\n\n", Header.biClrImportant);

    Header.biWidth = 16;
    Header.biHeight = 64;

////////////////////////////////////////////////////////////////////
// #1
    for(y = 0; y < Header.biHeight; y++){
        for(x = 0; x < Header.biWidth; x++){

            fread(&pixelValue, sizeof(unsigned char), 1, BMPFile);
            arr[(y*16)+x] = pixelValue;
            printf("0x%.2x, ",pixelValue);
            // printf("%d ",(y*16)+x); // to print the index counting -- I did it for testing

            if(x%16 == 15){printf("\n");} // this is because the lcd width is divided on 16 bytes = 128 bits 
        }
    }
    fclose(BMPFile);

////////////////////////////////////////////////////////////////////
// #2
// in this part I tried to reverse printing the array content but it works differently that the one that stores the bytes according to x, y indexing
    //for(x=1023; x>=0; x--){
    //    printf("0x%.2x, ",arr[x]);
    //    if(x%16 == 0){printf("\n");}
    //}

    return 0;
}





So, now what I do to test the array instead of uploading it to the microcontroller. I found a website that emulate exactly the resolution and the same shape on my LCD.

image2cpp

First it gives two options, upload and image or paste the array. So I copy the output of the code from output console window and paste it, then choose read as horizontal.


////////////////////////////////////////////////////////////////////////////////////////////////////
Now what I did:

Actually I only solved one problem, which is the misplacing of the picture by commenting this line:

    fread(&Header.Reserve1,           sizeof(Header.Reserve1) , 1, BMPFile);


It's already commented in the code I posted, but I couldn't flip the image vertically.

Here's an example array output to paste in the website:

0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x01, 0xf8, 0x1f, 0xf8, 0x1f, 0xf0, 0x3c, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x78, 0x0f, 0xf8, 0x1f, 0xf0, 0x1c, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x38, 0x0f, 0xf0, 0x1f, 0xf0, 0x1c, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x38, 0x0f, 0xf0, 0x0f, 0xf0, 0x1c, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x38, 0x0f, 0xe0, 0x0f, 0xf0, 0x1c, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x18, 0x0f, 0xe0, 0x07, 0xf0, 0x1c, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x18, 0x0f, 0xe0, 0x07, 0xf0, 0x1c, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x18, 0x0f, 0xc0, 0x07, 0xf0, 0x1c, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfe, 0x07, 0xff, 0xf0, 0x18, 0x0f, 0xc0, 0x03, 0xf0, 0x1c, 0x00, 0x00, 0x07, 0xff, 0xff,
0xff, 0xfe, 0x07, 0xff, 0xf0, 0x18, 0x0f, 0xc0, 0x03, 0xf0, 0x1c, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xfe, 0x07, 0xff, 0xf0, 0x18, 0x0f, 0x80, 0x01, 0xf0, 0x1c, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xfe, 0x07, 0xff, 0xf0, 0x38, 0x0f, 0x80, 0x01, 0xf0, 0x1c, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x38, 0x1f, 0x01, 0x81, 0xf0, 0x1c, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x38, 0x1f, 0x01, 0x80, 0xf0, 0x1c, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x78, 0x1f, 0x01, 0x80, 0xf0, 0x1c, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0xf8, 0x1e, 0x03, 0x80, 0xf0, 0x1c, 0x07, 0xff, 0x80, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x78, 0x1e, 0x03, 0xc0, 0x70, 0x1c, 0x07, 0xff, 0xc0, 0x7f, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x78, 0x1e, 0x03, 0xc0, 0x70, 0x1c, 0x07, 0xff, 0xc0, 0x7f, 0xff,
0xff, 0xfe, 0x07, 0xff, 0xc0, 0x38, 0x0c, 0x07, 0xe0, 0x70, 0x1c, 0x07, 0xff, 0xc0, 0x7f, 0xff,
0xff, 0xfe, 0x07, 0xff, 0xe0, 0x38, 0x0c, 0x07, 0xe0, 0x30, 0x1c, 0x07, 0xff, 0xc0, 0x7f, 0xff,
0xff, 0xfe, 0x07, 0xff, 0xe0, 0x38, 0x0c, 0x07, 0xe0, 0x30, 0x1c, 0x07, 0xff, 0xc0, 0x7f, 0xff,
0xff, 0xfe, 0x07, 0xff, 0xe0, 0x38, 0x18, 0x0f, 0xe0, 0x10, 0x1c, 0x07, 0xff, 0xc0, 0x7f, 0xff,
0xff, 0xfe, 0x07, 0xff, 0xe0, 0x38, 0x00, 0x0f, 0xf0, 0x10, 0x1c, 0x07, 0xff, 0x00, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x38, 0x00, 0x0f, 0xf0, 0x00, 0x1c, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x38, 0x00, 0x1f, 0xf8, 0x00, 0x1c, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x38, 0x00, 0x1f, 0xf8, 0x00, 0x1c, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x78, 0x00, 0x3f, 0xf8, 0x00, 0x1c, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x78, 0x00, 0x3f, 0xfc, 0x00, 0x1c, 0x00, 0x00, 0x01, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x3f, 0xfc, 0x00, 0x1c, 0x00, 0x00, 0x03, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x7f, 0xfc, 0x00, 0x1c, 0x00, 0x00, 0x0f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,


This is the actual image example:

Posted Image


///////////////////////////////////////////////////////////////////////////////////////////////////
1. I tried to comment/uncomment the fread lines, but I don't know what I'm doing exactly, the one of the misplacing was just by coincidence.
2. Also I want to know why commenting/uncommenting the fread lines, actually affect pixelValue ?
3. I want to learn how to control this code and know how to adjust it to what I want.


Thanks in advance,

Is This A Good Question/Topic? 0
  • +

Replies To: Converting bmp files to c array code problem

#2 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7665
  • View blog
  • Posts: 25,704
  • Joined: 05-May 12

Re: Converting bmp files to c array code problem

Posted 06 February 2021 - 10:46 PM

First, you need to open your file for reading binary, not text. So you'll want to pass in "rb", not just "r" to fopen().

Next, the correct procedure is to first read in the BITMAPFILEHEADER as a single fread() operation. You verify that that the file header looks like something that you are expecting to get. (e.g. bfType contains the correct signature bytes 'B' and 'M').

Next, the bfOffbits will tell you where to seek into the file to get to the beginning of that bitmap data. If that is all you are interested in, then you can seek there directly, but chances are you'll also want to know like whether the data is from top to bottom or bottom to top for the scanlines.

Next, you try to read in a BITMAPINFOHEADER as another single fread(). If the biSize doesn't equal sizeof(BITMAPINFOHEADER), then you'll need to see if the size equals sizeof(BITMAPV4HEADER) or sizeof(BITMAPV5HEADER), then backup to offset 14 and try reading in the appropriate type of bitmap information header.

If the height (biHeight, bv4Height, or bv5Height) is positive that means that the origin of the bitmap is the bottom left corner, otherwise the origin is the upper left corner.
Was This Post Helpful? 1
  • +
  • -

#3 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7665
  • View blog
  • Posts: 25,704
  • Joined: 05-May 12

Re: Converting bmp files to c array code problem

Posted 06 February 2021 - 10:57 PM

View Postwolfrose, on 06 February 2021 - 10:51 PM, said:

1. I tried to comment/uncomment the fread lines, but I don't know what I'm doing exactly, the one of the misplacing was just by coincidence.
2. Also I want to know why commenting/uncommenting the fread lines, actually affect pixelValue ?

That is because you have a typo on line 44:
fread(&Header.biPlanes,           sizeof(Header.biClrUsed),  1, BMPFile);


biPlanes which you declared as a short and only 2 bytes long, but you are using sizeof(biClrUsed) which you declared as long which is 4 bytes long. By skipping reading Reserved1 -- another short -- you compensate and get back in sync when it is time to read in the bitmap data.

View Postwolfrose, on 06 February 2021 - 10:51 PM, said:

3. I want to learn how to control this code and know how to adjust it to what I want.

Don't just copy code. Actually understand what it is trying to do.
Read MSDN: Bitmap Storage .
Was This Post Helpful? 2
  • +
  • -

#4 wolfrose   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 72
  • Joined: 20-January 16

Re: Converting bmp files to c array code problem

Posted 07 February 2021 - 12:03 AM

View PostSkydiver, on 06 February 2021 - 10:46 PM, said:

First, you need to open your file for reading binary, not text. So you'll want to pass in "rb", not just "r" to fopen().



This is the simplest thing I did so far :)

Quote

Next, the correct procedure is to first read in the BITMAPFILEHEADER as a single fread() operation. You verify that that the file header looks like something that you are expecting to get. (e.g. bfType contains the correct signature bytes 'B' and 'M').


I checked the microsoft website, but there are a lot of structs ! I don't know which one I should use.
I don't know even how it works.

1. I understood simple things; like, there's a relationship between the struct members and FILE functions like fread in this case.
2. Are the names of the struct, are they counted by how many members in the struct, the sequence of them in the struct, and if I used like one or couple of the members and commented the rest. How many do I exactly need in my current task ?



Quote

Next, the bfOffbits will tell you where to seek into the file to get to the beginning of that bitmap data. If that is all you are interested in, then you can seek there directly, but chances are you'll also want to know like whether the data is from top to bottom or bottom to top for the scanlines.


So how to use this member ? Should I modify it by myself or pass it to a function ?


Quote

Next, you try to read in a BITMAPINFOHEADER as another single fread(). If the biSize doesn't equal sizeof(BITMAPINFOHEADER), then you'll need to see if the size equals sizeof(BITMAPV4HEADER) or sizeof(BITMAPV5HEADER), then backup to offset 14 and try reading in the appropriate type of bitmap information header.


How to check for the sizes ? Do I use a simple if statement ?

Quote

If the height (biHeight, bv4Height, or [il]bv5Height[/ill) is positive that means that the origin of the bitmap is the bottom left corner, otherwise the origin is the upper left corner.


Yes, I think this point should resolve the main problem I have now, but I don't know how to do this.
Was This Post Helpful? 0
  • +
  • -

#5 wolfrose   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 72
  • Joined: 20-January 16

Re: Converting bmp files to c array code problem

Posted 08 February 2021 - 08:18 PM

Hi,

I developed a project to use microsoft Bitmap Storage data structures, with different types but I think I don't know how to use them.

I thought the use is direct, but I'm missing something.


#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

void bmp_bmi(FILE *bmp_arg);
void bmp_bf(FILE *bmp_arg);
void bmp_bi(FILE *bmp_arg);
void bmp_bV4(FILE *bmp_arg);

//////////////////////////////////////////////////////////
int main(){

    FILE *bmpfile = fopen("../bmp.bmp", "rb");

//bmp_bmi(bmpfile);
//bmp_bf(bmpfile);
//bmp_bi(bmpfile);
//bmp_bV4(bmpfile);

    return 0;
}

//////////////////////////////////////////////////////////


void bmp_bf(FILE *bmp_arg){

    BITMAPFILEHEADER bmp_main;

    fread(&bmp_main.bfType, sizeof(bmp_main.bfType), 1, bmp_arg);
    fread(&bmp_main.bfSize, sizeof(bmp_main.bfSize), 1, bmp_arg);
    fread(&bmp_main.bfReserved1, sizeof(bmp_main.bfReserved1), 1, bmp_arg);
    fread(&bmp_main.bfReserved2, sizeof(bmp_main.bfReserved2), 1, bmp_arg);
    fread(&bmp_main.bfOffBits, sizeof(bmp_main.bfOffBits), 1, bmp_arg);

    printf("bfType %d\n", bmp_main.bfType);
    printf("bfSize %ld\n", bmp_main.bfSize);
    printf("bfReserved1 %d\n", bmp_main.bfReserved1);
    printf("bfReserved2 %d\n", bmp_main.bfReserved2);
    printf("bfOffBits %ld\n", bmp_main.bfOffBits);

}


void bmp_bi(FILE *bmp_arg){
    BITMAPINFOHEADER bmp_info;
    int x, y;

    fread(&bmp_info.biBitCount, sizeof(bmp_info.biBitCount), 1, bmp_arg);
    fread(&bmp_info.biClrImportant, sizeof(bmp_info.biClrImportant), 1, bmp_arg);
    fread(&bmp_info.biClrUsed, sizeof(bmp_info.biClrUsed), 1, bmp_arg);
    fread(&bmp_info.biHeight, sizeof(bmp_info.biHeight), 1, bmp_arg);
    fread(&bmp_info.biPlanes, sizeof(bmp_info.biPlanes), 1, bmp_arg);
    fread(&bmp_info.biSize, sizeof(bmp_info.biSize), 1, bmp_arg);
    fread(&bmp_info.biWidth, sizeof(bmp_info.biWidth), 1, bmp_arg);
    fread(&bmp_info.biXPelsPerMeter, sizeof(bmp_info.biXPelsPerMeter), 1, bmp_arg);
    fread(&bmp_info.biYPelsPerMeter, sizeof(bmp_info.biYPelsPerMeter), 1, bmp_arg);
    fread(&bmp_info.biCompression, sizeof(bmp_info.biCompression), 1, bmp_arg);
    fread(&bmp_info.biSizeImage, sizeof(bmp_info.biSizeImage), 1, bmp_arg);

    printf("biBitCount %d\n", bmp_info.biBitCount);
    printf("biClrImportant %ld\n", bmp_info.biClrImportant);
    printf("biClrUsed %ld\n", bmp_info.biClrUsed);
    printf("biHeight %ld\n", bmp_info.biHeight);
    printf("biWidth %ld\n\n", bmp_info.biWidth);

    printf("biPlanes %d\n", bmp_info.biPlanes);
    printf("biSize %ld\n", bmp_info.biSize);
    printf("biXPelsPerMeter %ld\n", bmp_info.biXPelsPerMeter);
    printf("biYPelsPerMeter %ld\n", bmp_info.biYPelsPerMeter);
    printf("biCompression %ld\n", bmp_info.biCompression);
    printf("biSizeImage %ld\n", bmp_info.biSizeImage);

    for(y = 0; y < bmp_info.biHeight; y++){
        for(x = 0; x < bmp_info.biWidth; x++){

        }
    }
}


void bmp_bmi(FILE *bmp_arg){
    BITMAPINFO bmpi;
printf("\n------------------------------------------------------------------------\n");
printf("bmp_main_info ----------------------------------------------------------\n");
    ///////////////////////////////////////////////////////////////////////////////
    fread(&bmpi.bmiHeader, sizeof(bmpi.bmiHeader.biBitCount), 1, bmp_arg);
    fread(&bmpi.bmiHeader, sizeof(bmpi.bmiHeader.biClrImportant), 1, bmp_arg);
    fread(&bmpi.bmiHeader, sizeof(bmpi.bmiHeader.biClrUsed), 1, bmp_arg);
    fread(&bmpi.bmiHeader, sizeof(bmpi.bmiHeader.biCompression), 1, bmp_arg);
    fread(&bmpi.bmiHeader, sizeof(bmpi.bmiHeader.biHeight), 1, bmp_arg);
    fread(&bmpi.bmiHeader, sizeof(bmpi.bmiHeader.biPlanes), 1, bmp_arg);
    fread(&bmpi.bmiHeader, sizeof(bmpi.bmiHeader.biSize), 1, bmp_arg);
    fread(&bmpi.bmiHeader, sizeof(bmpi.bmiHeader.biSizeImage), 1, bmp_arg);
    fread(&bmpi.bmiHeader, sizeof(bmpi.bmiHeader.biWidth), 1, bmp_arg);
    fread(&bmpi.bmiHeader, sizeof(bmpi.bmiHeader.biXPelsPerMeter), 1, bmp_arg);
    fread(&bmpi.bmiHeader, sizeof(bmpi.bmiHeader.biYPelsPerMeter), 1, bmp_arg);

    printf(" //////////////// Header \n");
    printf("biBitCount %d\n", bmpi.bmiHeader.biBitCount);
    printf("biClrImportant %ld\n", bmpi.bmiHeader.biClrImportant);
    printf("biClrUsed %ld\n", bmpi.bmiHeader.biClrUsed);
    printf("biCompression %ld\n", bmpi.bmiHeader.biCompression);
    printf("biHeight %ld\n", bmpi.bmiHeader.biHeight);
    printf("biPlanes %d\n", bmpi.bmiHeader.biPlanes);
    printf("biSize %ld\n", bmpi.bmiHeader.biSize);
    printf("biSizeImage %ld\n", bmpi.bmiHeader.biSizeImage);
    printf("biWidth %ld\n", bmpi.bmiHeader.biWidth);
    printf("biXPelsPerMeter %ld\n", bmpi.bmiHeader.biXPelsPerMeter);
    printf("biYPelsPerMeter %ld\n", bmpi.bmiHeader.biYPelsPerMeter);

    ///////////////////////////////////////////////////////////////////////////////
    fread(&bmpi.bmiColors, sizeof(bmpi.bmiColors->rgbReserved), 1, bmp_arg);
    fread(&bmpi.bmiColors, sizeof(bmpi.bmiColors->rgbBlue), 1, bmp_arg);
    fread(&bmpi.bmiColors, sizeof(bmpi.bmiColors->rgbGreen), 1, bmp_arg);
    fread(&bmpi.bmiColors, sizeof(bmpi.bmiColors->rgbRed), 1, bmp_arg);

    printf(" //////////////// Colors \n");
    printf("Colors res %d\n", bmpi.bmiColors->rgbReserved);
    printf("Colors blue %d\n", bmpi.bmiColors->rgbBlue);
    printf("Colors green %d\n", bmpi.bmiColors->rgbGreen);
    printf("Colors red %d\n", bmpi.bmiColors->rgbRed);

}

void bmp_bV4(FILE *bmp_arg){
    BITMAPV4HEADER bmp_v4;
    int x, y;

    fread(&bmp_v4.bV4BitCount, sizeof(bmp_v4.bV4BitCount), 1, bmp_arg);
    fread(&bmp_v4.bV4ClrImportant, sizeof(bmp_v4.bV4ClrImportant), 1, bmp_arg);
    fread(&bmp_v4.bV4ClrUsed, sizeof(bmp_v4.bV4ClrUsed), 1, bmp_arg);
    fread(&bmp_v4.bV4CSType, sizeof(bmp_v4.bV4CSType), 1, bmp_arg);
    fread(&bmp_v4.bV4Endpoints, sizeof(bmp_v4.bV4Endpoints), 1, bmp_arg);
    fread(&bmp_v4.bV4Height, sizeof(bmp_v4.bV4Height), 1, bmp_arg);
    fread(&bmp_v4.bV4Planes, sizeof(bmp_v4.bV4Planes), 1, bmp_arg);
    fread(&bmp_v4.bV4Size, sizeof(bmp_v4.bV4Size), 1, bmp_arg);
    fread(&bmp_v4.bV4Width, sizeof(bmp_v4.bV4Width), 1, bmp_arg);

    printf("bV4BitCount %d\n", bmp_v4.bV4BitCount);
    printf("bV4ClrImportant %ld\n", bmp_v4.bV4ClrImportant);
    printf("bV4ClrUsed %ld\n", bmp_v4.bV4ClrUsed);
    printf("bV4CSType %ld\n", bmp_v4.bV4CSType);
    //printf("bV4Endpoints %ld\n", bmp_v4.bV4Endpoints);
    printf("bV4Height %ld\n", bmp_v4.bV4Height);
    printf("bV4Planes %d\n", bmp_v4.bV4Planes);
    printf("bV4Size %ld\n", bmp_v4.bV4Size);
    printf("bV4Width %ld\n", bmp_v4.bV4Width);



    for(y = 0; y < bmp_v4.bV4Height; y++){
        for(x = 0; x < bmp_v4.bV4Width; x++){

        }
    }




}





I was trying different data structures, but didn't get the info as in the example I copied from microchip forum ! I posted in the main post.
Was This Post Helpful? 0
  • +
  • -

#6 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7665
  • View blog
  • Posts: 25,704
  • Joined: 05-May 12

Re: Converting bmp files to c array code problem

Posted 09 February 2021 - 11:21 AM

No, you don't read in each part of the structure one at a time. You do it like this:
BITMAPFILEHEADER header = { 0 };

size_t bytesRead = fread(&header, sizeof(header), 1, bmp_arg);

if (bytesRead == sizeof(header))
{
    printf("bfType %d\n", header.bfType);
    printf("bfSize %ld\n", header.bfSize);
    printf("bfOffBits %ld\n", header.bfOffBits);
}



There's no point printing out the reserved values since they are reserved for internal use and should be opaque to you.
Was This Post Helpful? 1
  • +
  • -

#7 wolfrose   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 72
  • Joined: 20-January 16

Re: Converting bmp files to c array code problem

Posted 09 February 2021 - 06:00 PM

I was displaying the wrong types of structures in Microsoft website, I went back to your reply #2 and found the two types I need which are:

BITMAPFILEHEADER and BITMAPINFOHEADER


I modified the code and got the same results as the example code I copied but the same problem also.

When I copy the resulted array and paste it in this website, I get the same problems, the image is flipped upside down and split in two halves; also, there's a bit of not complete padding.

image2cpp

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <windows.h>


BITMAPFILEHEADER    Header1;
BITMAPINFOHEADER    Header2;



int main( void ){

    FILE *BMP1 = fopen ("../bmp.bmp", "rb");

    fread(&Header1.bfType,               sizeof(Header1.bfType), 1, BMP1);
    fread(&Header1.bfSize,               sizeof(Header1.bfSize), 1, BMP1);
    fread(&Header1.bfReserved1,               sizeof(Header1.bfReserved1), 1, BMP1);
    fread(&Header1.bfReserved2,               sizeof(Header1.bfReserved2), 1, BMP1);
    fread(&Header1.bfOffBits,               sizeof(Header1.bfOffBits), 1, BMP1);

    printf("Type:%hd  and Type in  %x\n", Header1.bfType,Header1.bfType);
    printf("bfSize %d\n", Header1.bfSize);
    printf("bfReserved1 %d\n", Header1.bfReserved1);
    printf("bfReserved2 %d\n", Header1.bfReserved2);
    printf("bfOffBits %d\n", Header1.bfOffBits);

    fread(&Header2.biSize,               sizeof(Header2.biSize), 1, BMP1);
    fread(&Header2.biWidth,              sizeof(Header2.biWidth), 1, BMP1);
    fread(&Header2.biHeight,             sizeof(Header2.biHeight), 1, BMP1);
    fread(&Header2.biPlanes,             sizeof(Header2.biPlanes), 1, BMP1);
    fread(&Header2.biBitCount,           sizeof(Header2.biBitCount), 1, BMP1);
    fread(&Header2.biCompression,        sizeof(Header2.biCompression), 1, BMP1);
    fread(&Header2.biSizeImage,          sizeof(Header2.biSizeImage), 1, BMP1);
    fread(&Header2.biXPelsPerMeter,      sizeof(Header2.biXPelsPerMeter), 1, BMP1);
    fread(&Header2.biYPelsPerMeter,      sizeof(Header2.biYPelsPerMeter), 1, BMP1);
    fread(&Header2.biClrImportant,       sizeof(Header2.biClrImportant), 1, BMP1);
    fread(&Header2.biClrUsed,            sizeof(Header2.biClrUsed), 1, BMP1);


    printf("biHeight %d \n",            Header2.biHeight);
    printf("biWidth %d \n",             Header2.biWidth);
    printf("biBitCount %d \n",          Header2.biBitCount);
    printf("biClrImportant %d \n",      Header2.biClrImportant);
    printf("biClrUsed %d \n",           Header2.biClrUsed);
    printf("biCompression %d \n",       Header2.biCompression);
    printf("biPlanes %d \n",            Header2.biPlanes);
    printf("biSize %d \n",              Header2.biSize);
    printf("biSizeImage %d \n",         Header2.biSizeImage);
    printf("biXPelsPerMeter %d \n",     Header2.biXPelsPerMeter);
    printf("biYPelsPerMeter %d \n",     Header2.biYPelsPerMeter);

    printf("Size of Header1 + Header2: %ld\n", sizeof(Header1)+sizeof(Header2));


//////////////////////////////////////////////////////////////////////////////////

int x = 0, y = 0;
uint8_t pixel;



    for(y=0; y<64; y++){
        for(x=0; x<16; x++){
            fread(&pixel,sizeof(pixel),1,BMP1);
            printf("0x%.2x, ",pixel);

            if(x%16 == 15){printf("\n");}
        }
    }



    return 0;
}

This post has been edited by wolfrose: 09 February 2021 - 06:01 PM

Was This Post Helpful? 0
  • +
  • -

#8 wolfrose   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 72
  • Joined: 20-January 16

Re: Converting bmp files to c array code problem

Posted 09 February 2021 - 06:49 PM

I had to comment these three lines to fix the center alignment problem:

//    fread(&Header2.biPlanes,             sizeof(Header2.biPlanes), 1, BMP1);
//    fread(&Header2.biBitCount,           sizeof(Header2.biBitCount), 1, BMP1);
//    fread(&Header2.biCompression,        sizeof(Header2.biCompression), 1, BMP1);


Still two problems:
1. flipped
2. padding

Posted Image

This post has been edited by wolfrose: 09 February 2021 - 06:50 PM

Was This Post Helpful? 0
  • +
  • -

#9 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7665
  • View blog
  • Posts: 25,704
  • Joined: 05-May 12

Re: Converting bmp files to c array code problem

Posted 09 February 2021 - 07:08 PM

You obviously didn't read and grasp the significance of post #6.

Delete lines 17-21 and replace with:
fread(&Header1, sizeof(Header1), 1, BMP1);



Delete lines 29-39 and replace with:
fread(&Header2, sizeof(Header2), 1, BMP1);



And you obviously still didn't read the link I provided in post #3 about how to read a bitmap from its storage location. The bitmap bits will not be immediately after the BITMAPINFOHEADER. There is usually a color table there before the actual data. The actual data starts at Header1.bfOffBits. You need to seek there if you want to start reading the bitmap data and skip over the color table.

Also in the same post #3, you ignored the fact that the I said that a positive value in Header2.biHeight indicates that the bitmap data is laid out from the bottom left going up, instead of from top left going down. That means you need to read in the scanlines of the bitmap an then flip them.
Was This Post Helpful? 2
  • +
  • -

#10 wolfrose   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 72
  • Joined: 20-January 16

Re: Converting bmp files to c array code problem

Posted 10 February 2021 - 10:33 PM

View PostSkydiver, on 09 February 2021 - 07:08 PM, said:

You obviously didn't read and grasp the significance of post #6.

Delete lines 17-21 and replace with:
fread(&Header1, sizeof(Header1), 1, BMP1);



Delete lines 29-39 and replace with:
fread(&Header2, sizeof(Header2), 1, BMP1);



Thanks for these lines, so instead of reading each struct member, I only have to read the struct object and that's it.

Quote

And you obviously still didn't read the link I provided in post #3 about how to read a bitmap from its storage location. The bitmap bits will not be immediately after the BITMAPINFOHEADER. There is usually a color table there before the actual data. The actual data starts at Header1.bfOffBits. You need to seek there if you want to start reading the bitmap data and skip over the color table.


I checked that link before and now too but still don't know how to read the bits and how to know the index of color bits.

I know that the header size is 54 bytes, I solved the problem of padding by adding this line which I copied from the previous example, but don't know actually what does it do.

    int   myPalette[2]; // at the beginning of the code

    fread(&Header1, sizeof(Header1), 1, BMP1);
    fread(&Header2, sizeof(Header2), 1, BMP1);
    fread(&myPalette[0], 4, 2, BMP1);



It solved the padding problem, I guess it skips 8 bytes. I tried to prove my assumption that it's 8 bytes, so I replaced the array of int which = 8 bytes to a long variable which is 8 bytes on 64-bit machine, but it didn't work. It has to be an array of 2 elements, each element is 4 bytes.

Quote

Also in the same post #3, you ignored the fact that the I said that a positive value in Header2.biHeight indicates that the bitmap data is laid out from the bottom left going up, instead of from top left going down. That means you need to read in the scanlines of the bitmap an then flip them.


Yes, I actually got some of what you meant but didn't know how to do it.
It tried storing the read bytes in an array and reverse their indexing. With this trick, but didn't work.

int x, y, i;
uint8_t pixel;

    for(i=1023; i >= 0; i--){    // as an effort to start storing bytes from the bottom of the array
        fread(&pixel,sizeof(pixel),1,BMP1);
        arr1[i] = pixel;
    }

     for(y=0; y<64; y++){
        for(x=0; x<16; x++){
            printf("0x%.2x, ",arr1[(y*16)+x]);
            if(x%16 == 15){printf("\n");}
        }
    }


This post has been edited by wolfrose: 10 February 2021 - 10:34 PM

Was This Post Helpful? 0
  • +
  • -

#11 wolfrose   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 72
  • Joined: 20-January 16

Re: Converting bmp files to c array code problem

Posted 11 February 2021 - 10:10 AM

OK, finally I did it :)

I learned one trick that I didn't notice when reversing reading the array out, is that I should read from the bottom most line of the array but at the same time I must increment x and decrement y to just flip vertically only, where decrementing both x and y was the mistake.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <windows.h>


BITMAPFILEHEADER    Header1;
BITMAPINFOHEADER    Header2;
RGBQUAD             Header3;


int main( void ){
    //int   myPalette[2];
    uint8_t arr1[1024];
    int   myPalette;

    FILE *BMP1 = fopen ("../bmp.bmp", "rb");

    fread(&Header1, sizeof(Header1), 1, BMP1);

    printf("Type:%hd  and Type in  %x\n", Header1.bfType,Header1.bfType);
    printf("bfSize %d\n", Header1.bfSize);
    printf("bfOffBits %d\n", Header1.bfOffBits);

    fread(&Header2, sizeof(Header2), 1, BMP1);
    fread(&myPalette, 4, 2, BMP1);

    printf("biHeight %d \n",            Header2.biHeight);
    printf("biWidth %d \n",             Header2.biWidth);
    printf("biBitCount %d \n",          Header2.biBitCount);
    printf("biClrImportant %d \n",      Header2.biClrImportant);
    printf("biClrUsed %d \n",           Header2.biClrUsed);
    printf("biCompression %d \n",       Header2.biCompression);
    printf("biPlanes %d \n",            Header2.biPlanes);
    printf("biSize %d \n",              Header2.biSize);
    printf("biSizeImage %d \n",         Header2.biSizeImage);
    printf("biXPelsPerMeter %d \n",     Header2.biXPelsPerMeter);
    printf("biYPelsPerMeter %d \n",     Header2.biYPelsPerMeter);

    printf("Size of Header1 + Header2  + Header3: %ld\n", sizeof(Header1)+sizeof(Header2));

//////////////////////////////////////////////////////////////////////////////////

int x, y, i;
uint8_t pixel;

    for(i=0; i < 1024; i++){
        fread(&pixel,sizeof(pixel),1,BMP1);
        arr1[i] = pixel;
    }

     for(y=63; y>=0; y--){
        for(x=0; x<16; x++){
            printf("0x%.2x, ",arr1[(y*16)+x]);
            if(x%16 == 15){printf("\n");}
        }
    }

    return 0;
}



I want to mark this thread as solved, how ? or just leave it as is ?
Was This Post Helpful? 0
  • +
  • -

#12 wolfrose   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 72
  • Joined: 20-January 16

Re: Converting bmp files to c array code problem

Posted 11 February 2021 - 11:34 AM

OK, I should have waited a bit before getting excited about getting away with one good output.

The code didn't work with other bmp files !

I have to write a code that can adapt any monochrome bmp file.

But why one works and other don't ?!
Was This Post Helpful? 0
  • +
  • -

#13 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7665
  • View blog
  • Posts: 25,704
  • Joined: 05-May 12

Re: Converting bmp files to c array code problem

Posted 11 February 2021 - 07:42 PM

Read post #3 again, specially the link at the end. Not all bitmaps are created the same way. You need to interpret the data in the headers. Like when I said that first header tells you where the bitmap data begins, and the second header tells you whether the rows are arranged from top to bottom or bottom up. The other fields of the various headers will tell you how many bits are used for each pixel, how the colors are supposed to be interpreted, or if the bitmap data is compressed or not.
Was This Post Helpful? 1
  • +
  • -

#14 wolfrose   User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 72
  • Joined: 20-January 16

Re: Converting bmp files to c array code problem

Posted 13 February 2021 - 06:04 AM

hi,

I found a simple solution that get any bmp to work with my code, which is to save the bmp in windows paint as monochrome with adjusting the height/length. Then it works without problems with my code.

Even, the website I provided the link to which converts bmp files, has the same issues, some bmp doesn't convert properly.

Because I want to use these bmp stuff in my embedded lcd with resolution of 128x64 that can work with monochrome bmp. I think this far is enough for this project.

My next project is tft LCDs that work with colored pictures and maybe with formats other than bmp, found this tutorial which is nice and providing a tool that converts pictures' formats like; bmp, png .. etc to C/C++ array. And provide different scaling techniques.

Converting Images to Flash Memory Icons/images for TFT (without SD Card)


Quote

You need to interpret the data in the headers.


The link is a bit general to me, not detailed and there's no sample codes to demonstrate the different techniques to read bmp files.

I need to learn how to read and interpret other types, but for now, the ones I save from windows paint are ok and working with my code.

But I now reached the point where I want to learn how to do the padding and how to do the alignment; as if I wanted to shift the output array to the right to get it in the center position.

I'm thinking now how to shift a whole 1024 array ? next how to do the padding for the black areas?

Quote

Like when I said that first header tells you where the bitmap data begins, and the second header tells you whether the rows are arranged from top to bottom or bottom up.


Couldn't figure out which variables that determine the arrangement of the bmp.

I thought biXPelsPerMeter or biYPelsPerMeter, but with different examples couldn't figure their role in direction of starting bits.

Quote

The other fields of the various headers will tell you how many bits are used for each pixel, how the colors are supposed to be interpreted, or if the bitmap data is compressed or not.


For example, this is one of the bmp I'm working on.

Type:19778  and Type in  4d42
bfSize 1086
bfOffBits 62
biHeight 64
biWidth 100
biBitCount 1
biClrImportant 0
biClrUsed 0
biCompression 0
biPlanes 1
biSize 40
biSizeImage 1024
biXPelsPerMeter 0
biYPelsPerMeter 0
Size of Header1 + Header2: 54


so bfSize 1086 I guess this is the whole bmp size, 1086 - 1024 = 62 I think 62 is the whole header size.

also, bfOffBits 62 proves that it's the actual bits start after 62 bytes.

where I'm reading 54 bytes, and I think 8 bytes for the color palette so it's 62.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1