21 августа 2014 г.

Работа с BMP файлом C++ преобразование изображения в массив

О том из чего состоит BMP файл я написал Здесь.

Мне нужно было написать программу которая конвертирует изображение в массив состоящий из 2 чисел, чтобы получилась матрица чёрно белого изображения, которую я могу использовать для работы с дисплеем от Nokia 5110.

Здесь лежит исходный код на c++, того что у меня получилось, теперь я немного опишу как он работает.

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

Я решил что для того чтобы открыть изображение в моей программе его следует бросить на .exe, для этого я использовал эти параметры в main: (int argc, char *argv[]), argc хранит значение аргументов которые мы передали программе, argv хранит строки которые мы передали программе.


1 Аргумент это имя программы (вместе с адресом c:/program.exe), 2 аргумент в моём случае адрес на файл который следует открыть.

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;
}


Значит аргументов всегда больше 1, т.к это имя программы. Я проверяю бросили ли файл в .exe, если да то вывожу его имя, если нет, то вывожу сообщение об ошибке и закрываю программу.

// Открываем файл
ifstream file (argv[1], ios::in | ios::binary);

// Переходим на 2 байт
file.seekg( 2, ios::beg);

// Считываем размер файла
file.read ((char*)&size, sizeof(int));

// Переходим на 10 байт
file.seekg( 10, ios::beg);

// Считываем адрес начала массива пикселей
file.read ((char*)&pixels_adress, sizeof(int));


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

// Считываем ширину и высоту изображения (в пикселях)
file.read ((char*)&width, sizeof(int));

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


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

// считываем кол-во битов на пиксель
file.read ((char*)&bits_per_pixel, sizeof(short int));

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

// Выводим всю информацию на экран
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;


У меня изображение должно быть 84х48 пикселей. Поэтому я точно знаю ширину и высоту и сразу создаю массив и использую числа в циклах. Далее я заполняю массив информацией о цвете (0 - белый, 1 - другой цвет ). Я расписал для каждого количества битов на пиксель, я покажу лишь 1. Напомню что цвета хранятся в памяти начиная с левого нижнего.
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;
  }
 }
}

После этого у меня есть готовый массив хранящий информацию о пикселях в 2 цветах как мне и нужно. 

Комментариев нет :

Отправить комментарий