Форматы растровых файлов
Изображения можно хранить в растровом (как массив пикселов) или векторном виде
(как набор примитивов). Любой графический файл состоит из заголовка
и данных. В заголовке располагаются:
1. Идентификатор формата (первые несколько байт). Например, в формате BMP это - 2 символа 'BM' (BitMap), в формате GIF - GIF87a.
2. Тип данных (RGB или палитра, тип упаковки, кол-во битов на пиксел)
3. Размеры изображения
4. Дополнительные параметры (разрешение, строка описания и т.п.)
Далее располагается палитра (если она требуется) и массив пикселов. В некоторых форматах начало палитры и массива пикселов указывается в заголовке, в других - они следуют непосредственно после него.
Формат BMP
struct BMP_header
{
char ID[2]; // 'BM' для Windows BitMap
long FSize; // размер файла
long Ver; // версия BMP (=0)
long Image; // положение изображения в файле
long Misc; // должно быть 40
long Width; // ширина изображения
long Height; // высота изображения
short Num; // кол-во изображений (должно быть =1)
short Bits; // кол-во бит на пиксел
// 1 - монохромная (2 значения в палитре), 4,8 - палитра, 24 - RGB
|
|
long Comp; // Тип компрессии, 0 - несжатый, 1 - RLE8, 2 - RLE4
long ISize; // размер изображения в байтах
long XRes; // кол-во точек на метр вдоль оси X
long YRes; // кол-во точек на метр вдоль оси Y
long PSize; // Кол-во индексов палитры (16 или 256)
long PImportant; //Кол-во важных для отображения индексов палитры (0 - все важные)
}; // 54 bytes
Палитра находится сразу после заголовка.
FILE *ifile=fopen("имя", "rb");
BMP_header bmp_header;
fread (&bmp_header, sizeof(bmp_header), 1, ifile);
if (bmp_header.Bits==24)
{
fseek(ifile,bmp_header.Image, SEEK_SET);
line_size=(bitmap_width*3+3)&0xFFFFFFFC;
unsigned char *line=new unsigned char[line_size];
for(y=bitmap_height-1;y>=0;y--)
{
fread (line, line_size, 1, ifile);
for(x=0;x<bitmap_width;x++)
bitmap[y*bitmap_width+x]=(line[x*3+2]<<16)+(line[x*3+1]<<8)+(line[x*3+0]<<0);
}
delete line;
}
else
if (bmp_header.Bits==8)
{
long Palette[256];
fread(Palette,256*4,1,ifile);
fseek(ifile,bmp_header.Image, SEEK_SET);
line_size=(bitmap_width+3)&0xFFFFFFFC;
unsigned char *line=new unsigned char[line_size];
for(y=bitmap_height-1;y>=0;y--)
{
fread (line, line_size, 1, ifile);
for(x=0;x<bitmap_width;x++)
bitmap[y*bitmap_width+x]=Palette[line[x]];
}
delete line;
}
Память, необходимая для хранения растрового изображения, вычисляется, как произведение его ширины на высоту и на количество бит на пиксел. К примеру, для хранения RGB фотографии 800 на 600 пикселей нужно примерно 1.4 мегабайта. Для ее передачи по internet c скоростью полтора килобайта (14400) в секунду нужно около 15 минут – т.е. довольно большое время. Или, к примеру, на хранение часового фильма, в котором 30 таких кадров в секунду, нужно 150 гигабайт. Таким образом, алгоритмы архивации информации, ориентированные на изображения, весьма актуальны.
Все алгоритмы сжатия изображений делятся на два класса: с потерей качества и без нее. В случае алгоритмов без потери качества, мы требуем полное побитовое соответствие сжатого и исходного изображений. В случае с потерей качества, мы жертвуем некоторой частью информации, в обмен на более сильную степень компрессии. Декомпрессированное изображение уже не будет полностью соответствовать исходному, однако часто человеческий глаз этого даже и не заметит.