BMP文件:
是Windows操作系統所推薦和支持的圖像文件格式,是一種將內存或顯示器的圖像數據不經過壓縮而直接按位存盤的文件格式,所以稱為位圖(bitmap)文件
BMP文件總體上由4部分組成:
位圖文件頭(bitmap-file header)14bytes
位圖信息頭(bitmap-information header)40bytes
彩色表/調色板(color table)
位圖數據(bitmap-data)
1.位圖文件頭(bitmap-file header)
位圖文件頭(bitmap-file header)包含了圖像類型、圖像大小、圖像數據存放地址和兩個保留未使用的字段
打開WINGDI.h文件,搜索"BITMAPFILEHEADER"就可以定位到BMP文件的位圖文件頭的數據結構定義
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
字 段 名 大小(單位:字節) 描 述
bfType 2 位圖類別,根據不同的操作系統而不同,在Windows中,此字段的值總為‘BM’
bfSize 4 BMP圖像文件的大小,包括這14個字節
bfReserved1 2 總為0
bfReserved2 2 總為0
bfOffBits 4 從文件頭到實際的位圖數據的偏移字節數
bfOffBits 從文件頭開始到顏色數據的偏移量 54+sizeof(RGBQUAD)*256
bfSize 圖片的大小,bfOffBits + 長 X 寬 X 位數 例如對於128X128X24位的圖像 bfSize=128X128X24 + 54+sizeof(RGBQUAD)*256
2.位圖信息頭(bitmap-information header)
位圖信息頭(bitmap-information header)包含了位圖信息頭的大小、圖像的寬高、圖像的色深、壓縮說明圖像數據的大小和其他一些參數
打開WINGDI.h文件,搜索"tagBITMAPINFOHEADER"就可以定位到BMP文件的位圖信息頭的數據結構定義
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
字 段 名 大小(單位:字節) 描 述
biSize 4 本結構的大小,根據不同的操作系統而不同,在Windows中,此字段的值總為28h字節=40字節
biWidth 4 位圖的寬度,單位是像素
biHeight 2 位圖的高度,單位是像素
biPlanes 2 固定值1
biBitCount 2 每個像素的位數(1-黑白圖,4-16色,8-256色,24-真彩色)
biCompression 4 壓縮方式,BI_RGB(0)為不壓縮
biSizeImage 4 實際的位圖數據占用的字節數,BI_RGB時可設為0
biXPelsPerMeter 4 水平分辨率,單位像素/m
biYPelsPerMeter 4 垂直分辨率,單位像素/m
biClrUsed 4 指定本圖象實際用到的顏色數,如果該值為零,則用到的顏色數為2biBitCount
biClrImportant 4 重要的顏色數,此值為0時所有顏色都重要,對於使用調色板的BMP圖像來說,當顯卡不能夠顯示所有顏色時,此值將輔助驅動程序顯示顏色
3.彩色表/調色板(color table)
彩色表/調色板(color table)是單色、16色和256色圖像文件所特有的,相對應的調色板大小是2、16和256,調色板以4字節為單位,每4個字節存放一個顏色值,圖像 的數據是指向調色板的索引
可以將調色板想象成一個數組,每個數組元素的大小為4字節,假設有一256色的BMP圖像的調色板數據為:
調色板[0]=黑、調色板[1]=白、調色板[2]=紅、調色板[3]=藍…調色板[255]=黃
圖像數據01 00 02 FF表示調用調色板[1]、調色板[0]、調色板[2]和調色板[255]中的數據來顯示圖像顏色
在早期的計算機中,顯卡相對比較落后,不一定能保證顯示所有顏色,所以在調色板中的顏色數據應盡可能將圖像中主要的顏色按順序排列在前面,位圖信息 頭的biClrImportant字段指出了有多少種顏色是重要的
每個調色板的大小為4字節,按藍、綠、紅存儲一個顏色值
打開WINGDI.h文件,搜索"tagRGBTRIPLE"就可以定位到BMP文件的調色板的數據結構定義
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
字 段 名 大小(單位:字節) 描 述
rgbBlue 1 藍色的亮度(值范圍為0-255)
rgbGreen 1 綠色的亮度(值范圍為0-255)
rgbRed 1 紅色的亮度(值范圍為0-255)
rgbReserved 2 保留,總為0
說明:
調色板實際上是一個數組,共有biClrUsed個元素(如果該值為零,則有2biBitCount個元素)
8:256色圖,通常說的灰度圖
16:64K圖,一般沒有調色板,圖像數據中每兩個字節表示一個像素,5個或6個位表示一個RGB分量
24:16M真彩色圖,一般沒有調色板,圖像數據中每3個字節表示一個像素,每個字節表示一個RGB分量
32:4G真彩色,一般沒有調色板,每4個字節表示一個像素,相對24位真彩圖而言,加入了一個透明度,即RGBA模式
4.位圖數據(bitmap-data)
對於用到調色板的位圖,圖象數據就是該象素顏在調色板中的索引值。對於真彩色圖,圖象數據就是實際的R、G、B值
對於2色位圖,用1位就可以表示該象素的顏色(一般0表示黑,1表示白),所以一個字節可以表示8個象素。
對於16色位圖,用4位可以表示一個象素的顏色,所以一個字節可以表示2個象素。(要顯示16個顏色 2的4次方)因此4位就能表示一個像素
對於256色位圖,一個字節剛好可以表示1個象素。
對於真彩色圖,三個字節才能表示1個象素,哇,好費空間呀!沒辦法,誰叫你想讓圖的顏色顯得更亮麗呢,有得必有失嘛
如果圖像是單色、16色和256色,則緊跟着調色板的是位圖數據,位圖數據是指向調色板的索引序號。
如果位圖是16位、24位和32位色,則圖像文件中不保留調色板,即不存在調色板,圖像的顏色直接在位圖數據中給出。
16位圖像使用2字節保存顏色值,常見有兩種格式:5位紅5位綠5位藍和5位紅6位綠5位藍,即555格式和565格式。555格式只使用了15 位,最后一位保留,設為0。
24位圖像使用3字節保存顏色值,每一個字節代表一種顏色,按紅、綠、藍排列。
32位圖像使用4字節保存顏色值,每一個字節代表一種顏色,除了原來的紅、綠、藍,還有Alpha通道,即透明色。
如果圖像帶有調色板,則位圖數據可以根據需要選擇壓縮與不壓縮,如果選擇壓縮,則根據BMP圖像是16色或256色,采用RLE4或RLE8壓縮算 法壓縮
補充:
(1)位圖全部的像素,是按照自下向上,自左向右的順序排列的
RGB數據也是倒着念的,原始數據是按B、G、R的順序排列的
(2)因為32位的Windows操作系統處理4個字節(32位)的速度比較快,所以BMP的每一行顏色占用的字節數規定為4的整數倍。MyBmp.bmp中一行顏色有兩個像素,共占用6字節,如果要補齊4*2=8字節,就要再加兩個0字節
行補位的公式為:widthBytes = (width*biBitCount+31)/32*4
參數說明:Width:位圖的實際寬度
biBitCount:每個像素的位數
1-黑白圖,4-16色,8-256色,24-真彩色
typedef
struct
tagBITMAPINFO{
BITMAPINFOHEADER bmiHeader;
//位圖信息頭
RGBQUAD bmiColors[1];
//顏色表
}__attribute__((packed)) BITMAPINFO;
參考鏈接:https://www.cnblogs.com/lzlsky/archive/2012/08/16/2641698.html
https://baike.baidu.com/item/BMP/35116
https://blog.csdn.net/av_geek/article/details/18814073