Струткутра BMP файла
Primary tabs
Forums:
Как отобразить BMP картинку на эльфе. Руководство от cbn версия 0.1
http://cbn.narod.ru/AboutBMP.txt
1. ОПИСАНИЕ ФОРМАТА BMP
BMP файл начинается с заголовка (см. приложение 1).
Из заголовка вам понадобятся:
int по смещению 18 - ширина изображения, 22 - высота,
10 - начало изображения(от начала файла), 50 - число "важных" цветов палитры,
short на 28 - бит на пиксел.
После заголовка по смещению 54 начинается палитра цветов (есть только для 8 битных изобр.)
В палитре каждый цвет задается 4 байтами 0RGB. Далее каждое значение цвета представляет
собой индекс в этой палитре. Сколько всего в палитре цветов задано в int заголовка по смещ. 50
За ней по смещению, заданному в поле 10, расположено само изображение.
Число байт на пиксел считается как число бит/8. Если 1, то это индекс в палитре.
Изображение расположено по строкам, выравненным на границу 4, т.е.
если ширина изобр. некратна 4, то к каждой строке добавл. нули,
например ширина = 13 и режим 8 бит на пиксел - строка занимает 13 байт
- расширяется до 16 байт.
Строки располагаются в обратном порядке, т.е. снизу вверх.
2. ВЫВОД BMP НА ЭКРАН
//В примере TED от Rst7 есть функция вывода имиджа на экран:
void DrwImg(IMGHDR *img, int x, int y, int *pen, int *brush)
{
RECT rc;
DRWOBJ drwobj;
StoreXYWHtoRECT(&rc,x,y,img->w,img->h);
SetPropTo_Obj5(&drwobj,&rc,0,img);
SetColor(&drwobj,pen,brush);
DrawObject(&drwobj);
}
//Вызывается так:
DrwImg((IMGHDR *)&img,2,3,GetPaletteAdrByColorIndex(0),GetPaletteAdrByColorIndex(1));
//где 2,3 координаты на экране x и y.
//имидж описан как:
const IMGHDR img={132,176,5,0,(char *)bmp};
//8 бит изобр.132х176, bmp содержит данные цветов размером 132x176 байт.
//в swilib.h структура IMGHDR задана как:
typedef struct
{
char w;
char h;
char bpnum; //For BW=1, 8bit=5, 16bit=8, 0x80 - packed
char zero;
char *bitmap;
}IMGHDR;
//где w,h ширина и высота изображения, bpnum наш режим:
//5 = 8bit(RGB332), 8 = 16bit(RGB565), bitmap - сами данные пикселов.
//макросы преобраз-я цветов:
#define RGB8(R,G,B) (B+(G<<2)+(R<<5))
#define RGB16(R,G,B) ((B>31?31:B)+((G>63?63:G)<<5)+((R>31?31:R)<<11))
Дописать преобр.пикселов оставляю вам самим :)
ПРИЛОЖЕНИЕ 1. Заголовок графического формата BMP
------------------
смещ. размер имя
00 2 'BM'
02 4 Размер файла в байтах;
06 2 0
08 2 0
10 4 Смещение начала изображения в файле;
14 4 Размер этого заголовка, 40;
18 4 Ширина изображения в пикселях;
22 4 Высота изображения в пикселях;
26 2 Число плоскостей изображения, 1;
28 2 Бит на пиксел: 1,4,8,16,24,32;
30 4 Тип сжатия;
34 4 Размер сжатого изображения в байтах или 0;
38 4 Горизонтальное разрешение, в пикселях / на метр;
42 4 Вертикальное разрешение, в пикселях / на метр;
46 4 Количество используемых цветов;
50 4 Число "важных" цветов;
54 4*N Карты цветов BGRР;
BMP заголовок 54 б + палитра 4*256(вместо 256 число "важных" цветов);
строки повернуты, выравнены на границу кратную 4
----------
ПРИЛОЖЕНИЕ 2. Структуры заголовка BMP
--------------------------------------
//ЧИТАЕМ примечание в конце!!!
#pragma pack(1)
struct BMP_header {
unsigned short BMP_id ; // 'B''M'
unsigned long size, // size in bytes of the BMP file
zero_res, // 0
offbits, // 54
biSize, // 0x28
Width, // X
Height; // Y
unsigned short biPlanes, // 1
biBitCount ; // 24
unsigned long biCompression, // 0 = BI_RGB
biSizeImage, // 0
biXPelsPerMeter, // 0xB40
biYPelsPerMeter, // 0xB40
biClrUsed, file://0
biClrImportant; file://0
};
struct BMPst{
unsigned short bfType;
unsigned long bfSize;
unsigned short bfReserved1,
bfReserved2;
unsigned long bfOffBits,
biSize,
biWidth,
biHeight;
unsigned short biPlanes,
biBitCount;
unsigned long biCompression,
biSizeImage,
biXPelsPerMeter,
biYPelsPerMeter,
biClrUsed,
biClrImportant;
};
#pragma pack()
---------------------
ПРИЛОЖЕНИЕ 3. Функции перекодировки цветов
Чтобы Вам было легче работать и не мучиться
с переводом цветов разных битностей выложил ф-ции.
Если заканч. на ...tobyte переводим в 8 бит, ...toshort в 16
inline unsigned char rgb888tobyte(int color){
return ((color>>6)&3)|((color>>11)&0x1C)|((color>>16)&0xE0); }
inline short rgb888toshort(int color){
return ((color>>3)&0x1f)|((color>>5)&0x7e0)|((color>>8)&0xf800); }
inline unsigned char rgb565tobyte(short color){
return ((color>>3)&3)|((color>>6)&0x1C)|((color>>8)&0xE0); }
inline short rgb565toshort(short color){
return color; }
------------------
ПРИМЕЧАНИЕ:
ВАЖНО!!!
НЕ забываем про выравнивание на АРМ, т.е. *(int*)(bmp+10) = pickoff (граница некратна 4м!)
Нужно собирать по байтам: bmp[10]+(bmp[11]<<8)+(bmp[12]<<16)+(bmp[13]<<24);
Поэтому вышеуказанные структуры bmp вам не пригодятся :(
- Log in to post comments
- 2981 reads