суббота, 13 ноября 2010 г.

Работа с изображениями (начало начал)

В данном сообщении даются  базовые навыки работы с bmp.

План статьи:
  1. BMP и представление изображения  в памяти.
  2. Как явно открыть BMP
Подробно расписывать BMP я не стану, подробная спецификация формата дана http://ru.wikipedia.org/wiki/BMP
Это самый простой формат, с него надо начинать работать
Файл состоит из следующих частей:

BITMAPFILEHEADER - важное поле
BITMAPINFOHEADER - информация о изображение важные поля:
biBitCount, biWidth, biHeight - ЭТИХ ПАРАМЕТРОВ ДОСТАТОЧНО ЧТОБЫ ОТКРЫТЬ СТАНДАРТНЫЙ ФАЙЛ 24BIT
Палитра - для 8 битных раскрашиваемых изображений (в принципе сейчас не используется)
Само изображение
ВАЖНО!!! Изображение больше чем biWidth*biHeight, по историческим причинам biWidth реальный должен делиться на 4, по это realWidth = biWidth+biWidth%4 



Код позаимствовал с http://www.vbforums.com/showthread.php?t=261522 структуры BITMAPFILEHEADER и BITMAPFILEHEADER если надо можно позаимствовать по же этому адресу. Примечание для GNU программистов WORD - 16 бита (int)  DWORD и LONG - 32 бита (long)  

//Данная функция открывает bmp файл (на выходе имеем указатель на данные + заполненную структуру bitmapInfoHeader)

unsigned char * openBMP(char* filename, BITMAPINFOHEADER *bitmapInfoHeader)
{
 FILE *filePtr; //указатель на файл
 BITMAPFILEHEADER bitmapFileHeader; //информация о файле
 unsigned char *bitmapImage; //указатель на данные в которые будем писать изображение
 //открываем файл
 filePtr = fopen(filename,"rb");
 if (NULL == filePtr)
 {
   return NULL;
 }
 //считываем структуру BITMAPFILEHEADER
 fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER,1,filePtr);

 //читаем заголовок изображения
 fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER),1,filePtr);

 //перемещаем указать в файле на начало данных изображения
 fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);




 //Далее нам нужно запросить память под изображение
 // (в стандарте для не сжатого BMP bitmapInfoHeader->biSizeImage может равняться 0)
 long imsize = 0;
 long w =  bitmapInfoHeader->biWidth;
 long wstep = w+w%4;
 long h = bitmapInfoHeader->biHeight;
 if(0!=bitmapInfoHeader->biSizeImage)
 {
   imsize =  bitmapInfoHeader->biSizeImage;
 }else{
   imsize = wstep * h;
 } 
 bitmapImage = (unsigned char*)malloc(imsize);
     
 //читаем изображение
 fread(bitmapImage,imsize,filePtr);
         
 //Закрываем изображение 
 fclose(filePtr); 
 return bitmapImage;
}

В данном примере мы предпологаем что открываем BMP стандартое 3 канала 8 бит каждый канал.

так как "чистые" bmp - файлы в наше время экзотике в основном приходится работать с JPEG, PNG (интернет) или TIFF (медицина, наука), то данный пример просто для общего развития. Перечисленные форматы имеют намного более сложную структуру и данные сжаты алгоритмами, по этому они не открываются простым "способом".

В следующем сообщение я распишу как упростить данную процедуру с помощью готовых библиотек и открывать другие типы файлов.







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

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