Monday, September 29, 2014

Working with BMP file C++ convert image in to an array

I described insides of the BMP file Here.

I needed a program which converts bmp image in a 2 dimensional array of 0 and 1. So i could display the image on the LCD display from Nokia 5110.

Here I have the source code, written in C++, now i will explain how it works.

int main(int argc, char *argv[])



I decided that, in order to open the image file with my program it should be drag dropped on my .exe, that's why i used parameters in main: (int argc, char *argv[]), argc holds the number of arguments that we have passed to our program, argv holds strings that we have sended to our program. 1 argument is the name and location of the program. e.g. "C:/Banana/program.exe". 2 argument, in my case is the address to my image.

if (argc >= 2 )
    cout << "Your file is: " << argv[1] << endl;

else
{
    cout << "Please drag and drop .bmp file on the .exe" << endl;
    system("PAUSE");
    return 0;
}

argc is always more than 1, because 1 is our program adress. I check whether the user have dropped image onto my .exe, if yes i display some info, if not, i show a warning  and close the program.

// open the file
ifstream file (argv[1], ios::in | ios::binary);

// Go to the 2 byte
file.seekg( 2, ios::beg);

// read size of the file
file.read ((char*)&size, sizeof(int));

// Go to the 10 byte
file.seekg( 10, ios::beg);

// where pixels data is located
file.read ((char*)&pixels_adress, sizeof(int));


file.seekg( 18, ios::beg);

// width and height of the image (in pixels)
file.read ((char*)&width, sizeof(int));

file.read ((char*)&height, sizeof(int));


file.seekg( 28, ios::beg);

// Read number of bytes used per pixel
file.read ((char*)&bits_per_pixel, sizeof(short int));

file.seekg( pixels_adress, ios::beg);

// Display all of the info
cout << "Size: " << size << endl;
cout << "pixels_adress: " << pixels_adress << endl;
cout << "bits per pixel: " << bits_per_pixel << endl;
cout << "Width: " << width << endl;
cout << "Height: " << height << endl;

My image should always be exactly 84 by 48 pixels. That's why i already know size of my array and number of elements. I fill array with color data (0 - white, 1 - other color). My program can convert image with any bpp number (bits per pixel), I will show only 1.
Let me remind you that the colors are stored in memory starting from the lower left pixel.

char map[84][48];

if( bits_per_pixel == 24 )
{
 unsigned int bgr = 0;

 for( int y = 47; y >= 0; y-- )
 {
  for( int x = 0; x < 84; x++ )
  {
   file.read ((char*)&bgr, 3);

   if ( bgr == 0xFFFFFF ) 
    map[x][y] = '0';
   else
    map[x][y] = '1';

   bgr = 0;
  }
 }
}

In the end I receive file which contains information about our image and can be added to the existing AVR code.

No comments :

Post a Comment