from:https://blog.csdn.net/qingchuwudi/article/details/25785307
位圖(bmp)文件格式分析
作者:深藍(由博主分享)
一、什么是位圖
計算機能以位圖和矢量圖格式顯示圖像。
1、位圖(Bitmap):
圖像又稱點陣圖或光柵圖,它使用我們稱為像素(象素,Pixel)的一格一格的小點來描述圖像。計算機屏幕其實就是一張包含大量像素點的網格。當我們把位圖放大時,每一個像素小點看上去就像是一個個馬賽克色塊。
2、矢量圖(Vector)
使用直線和曲線來描述圖形,這些圖形的元素是一些點、線、矩形、多邊形、圓和弧線等等,它們都是通過數學公式計算獲得的。
位圖和矢量圖最簡單的區別就是:矢量圖可以無限放大,而且不會失真;而位圖則不能。
像Photoshop(PS)這樣主要用于處理位圖的軟件,我們稱之為圖像處理軟件;專門處理矢量圖的軟件,我們稱之為圖形設計軟件,例如Adobe Illustrator,CorelDRAW,Flash MX等。
二、BMP位圖文件
常見的圖像文件格式有:BMP、JPG(JPE,JPEG)、GIF等。
BMP圖像文件(Bitmap-File)格式是Windows采用的圖像文件存儲格式,在Windows環境下運行的所有圖像處理軟件都支持這種格式。Windows 3.0以后的BMP文件都是指設備無關位圖(DIB,device-independent bitmap)。BMP位圖文件默認的文件擴展名是.BMP,有時它也會以.DIB或.RLE作擴展名。
注:本文采用lena.bmp(512×512)做例子:
1、BMP文件結構
BMP文件由4部分組成:
1.?? 位圖文件頭(bitmap-file header)
2.?? 位圖信息頭(bitmap-informationheader)
3.?? 顏色表(color table)
4.?? 顏色點陣數據(bits data)
24位真彩色位圖沒有顏色表,所以只有1、2、4這三部分。
------------------------------------------------------------------------------------------------------------------------------------------------
看圖像屬性,位深度,如果是24,就說明圖片是24位真彩色
------------------------------------------------------------------------------------------------------------------------------------------------
用UltraEdit打開lena.bmp,可以看到這個文件的全部數據如下圖所示:
?
1、1位圖文件頭(BITMAPFILEHEADER)
?
位圖文件頭分4部分,共14字節:
名稱 | 占用空間 | 內容 | 實際數據 |
bfType | 2字節 | 標識,就是“BM”二字 | BM |
bfSize | 4字節 | 整個BMP文件的大小 | 0x000C0036(786486)【與右鍵查看圖片屬性里面的大小值一樣】 |
bfReserved1/2 | 4字節 | 保留字,沒用 | 0 |
bfOffBits | 4字節 | 偏移數,即 位圖文件頭+位圖信息頭+調色板 的大小 | 0x36(54) |
注意,Windows的數據是倒著念的,這是PC電腦的特色。如果一段數據為50?1A?25 3C,倒著念就是3C 25 1A50,即0x3C251A50。因此,如果bfSize的數據為36 00 0C 00,實際上就成了0x000C0036,也就是0xC0036。
?
1、2位圖信息頭(BITMAPINFOHEADER )
位圖信息頭共40字節:
名稱 | 占用空間 | 內容 | 實際數據 |
biSize | 4字節 | 位圖信息頭的大小,為40 | 0x28(40) |
biWidth | 4字節 | 位圖的寬度,單位是像素 | 0x200(512) |
biHeight | 4字節 | 位圖的高度,單位是像素 | 0x200(512) |
biPlanes | 2字節 | 固定值1 | 1 |
biBitCount | 2字節 | 每個像素的位數 1-黑白圖,4-16色,8-256色,24-真彩色 | 0x18(24) |
biCompression | 4字節 | 壓縮方式,BI_RGB(0)為不壓縮 | 0 |
biSizeImage | 4字節 | 位圖全部像素占用的字節數,BI_RGB時可設為0 | 0x0C |
biXPelsPerMeter | 4字節 | 水平分辨率(像素/米) | 0 |
biYPelsPerMeter | 4字節 | 垂直分辨率(像素/米) | 0 |
biClrUsed | 4字節 | 位圖使用的顏色數 如果為0,則顏色數為2的biBitCount次方 | 0 |
biClrImportant | 4字節 | 重要的顏色數,0代表所有顏色都重要 | 0 |
作為真彩色位圖,我們主要關心的是biWidth和biHeight這兩個數值,兩個數值告訴我們圖像的尺寸。biSize,biPlanes,biBitCount這幾個數值是固定的。想偷懶的話,其它的數值可以一律用0來填充。
?
?
1、3顏色表
24位真彩色位圖沒有顏色表。為了簡化,只討論24位真彩色位圖。
1、4顏色點陣數據
位圖全部的像素,是按照自下向上,自左向右的順序排列的。
RGB數據也是倒著念的,原始數據是按B、G、R的順序排列的。
三、Photoshop和Windows的BMP文件比較
Windows的BMP文件最后少了兩個0字節,沒有整體補位。bfSize(文件大小),biSizeImage(全部像素大小)也相應地減去2。
打開Photoshop,新建一個尺寸為2*3像素的文件:
?
放大圖片到最大(1600%),然后用鉛筆工具對每個像素都點一個不同顏色的點,如下圖所示:
?
儲存這個文件為BMP格式,文件名為“MyBmp.bmp”,在BMP選項中選擇Windows,24位:
?
?
?
你應該注意到圖中用黑色框起來的00 00了,在每行顏色的末尾添加的兩個0字節,是為了行補位。為什么要行補位呢?因為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-真彩色
注:Phtoshop在文件的末尾還補充了兩個0字節,好像是要整體補位。不過我看過的BMP資料中都沒有提到還要整體補位的,其它軟件生成的BMP文件也沒有整體補位的,這看起來像是Adobe的獨創,不知道目的何在。
PS:文章最后注的內容將由下篇文章解釋
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
from:https://www.cnblogs.com/lzlsky/archive/2012/08/16/2641698.html
BITMAPFILEHEADER、BITMAPINFOHEADER及BMP結構詳解
位圖BITMAPINFOHEADER 與BITMAPFILEHEADER:
先來看BITMAPINFOHEADER,只寫幾個主要的
????biSize包含的是這個結構體的大小(包括顏色表)
????biWidth和biHeight分別是圖片的長寬
????biPlanes是目標繪圖設備包含的層數,必須設置為1
????biBitCount是圖像的位數,例如24位,8位等
????biXPelsPerMeter, biYPelsPerMeter 是現實世界中每米包含的像素數 設為3780即可
????biSizeImage 圖像數據的大小 = biWidth X biHeight X biBitCount
????---------------------------------------------------------------------------------
????再看 BITMAPFILEHEADER
????bfType??圖片的類型 必須是BM 填0x4d42即十進制的19778
????bfOffBits 從文件頭開始到顏色數據的偏移量??54+sizeof(RGBQUAD)*256
????bfSize??圖片的大小,bfOffBits + 長 X 寬 X 位數??例如對于128X128X24位的圖像??bfSize=128X128X24 + 54+sizeof(RGBQUAD)*256
????bfReserved1和bfReserved1必須為0
BMP文件結構及其存取
數字圖像在外存儲器設備中的存儲形式是圖像文件,圖像必須按照某個已知的、公認的數據存儲順序和結構進行存儲,才能使不同的程序對圖像文件順利進行打開或存盤操作,實現數據共享。圖像數據在文件中的存儲順序和結構稱為圖像文件格式。目前廣為流傳的圖像文件格式有許多種,常見的格式包括BMP、 GIF、JPEG、TIFF、PSD、DICOM、MPEG等。在各種圖像文件格式中,一部分是由某個軟硬件廠商提出并被廣泛接受和采用的格式,例如 BMP、GIF和PSD格式;另一部分是由各種國際標準組織提出的格式,例如JPEG、TIFF和DICOM,其中JPEG是國際靜止圖像壓縮標準組織提出的格式,TIFF是由部分廠商組織提出的格式,DICOM是醫學圖像國際標準組織提出的醫學圖像專用格式。
BMP文件是Windows操作系統所推薦和支持的圖像文件格式,是一種將內存或顯示器的圖像數據不經過壓縮而直接按位存盤的文件格式,所以稱為位圖(bitmap)文件,因其文件擴展名為BMP,故稱為BMP文件格式,簡稱BMP文件。本書對圖像的算法編程都是針對BMP圖像文件的,因此在本章中我們詳細介紹BMP文件結構及其讀寫操作,以加深對圖像數據的理解。
BMP文件總體上由4部分組成,分別是位圖文件頭、位圖信息頭、調色板和圖像數據,如表5-1所示。 表5-1 BMP文件的組成結構
下面來詳細看一下每個組成部分的細節。 1.位圖文件頭(bitmap-file header) 位圖文件頭(bitmap-file header)包含了圖像類型、圖像大小、圖像數據存放地址和兩個保留未使用的字段。 打開WINGDI.h文件,搜索"BITMAPFILEHEADER"就可以定位到BMP文件的位圖文件頭的數據結構定義。
表5-2列出了tagBITMAPFILEHEADER中各字段的含義。 表5-2 tagBITMAPFILEHEADER結構
2.位圖信息頭(bitmap-information header) 位圖信息頭(bitmap-information header)包含了位圖信息頭的大小、圖像的寬高、圖像的色深、壓縮說明圖像數據的大小和其他一些參數。 打開WINGDI.h文件,搜索"tagBITMAPINFOHEADER"就可以定位到BMP文件的位圖信息頭的數據結構定義。
表5-3列出了tagBITMAPFILEHEADER中各字段的含義。 表5-3 tagBITMAPFILEHEADER結構
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3.彩色表/調色板(color table) 彩色表/調色板(color table)是1色、16色和256色圖像文件所特有的,相對應的調色板大小是2、16和256,調色板以4字節為單位,每4個字節存放一個顏色值,圖像 的數據是指向調色板的索引。 可以將調色板想象成一個數組,每個數組元素的大小為4字節,假設有一256色的BMP圖像的調色板數據為:
圖像數據01 00 02 FF表示調用調色板[1]、調色板[0]、調色板[2]和調色板[255]中的數據來顯示圖像顏色。 在早期的計算機中,顯卡相對比較落后,不一定能保證顯示所有顏色,所以在調色板中的顏色數據應盡可能將圖像中主要的顏色按順序排列在前面,位圖信息 頭的biClrImportant字段指出了有多少種顏色是重要的。 每個調色板的大小為4字節,按藍、綠、紅存儲一個顏色值。 打開WINGDI.h文件,搜索"tagRGBTRIPLE"就可以定位到BMP文件的調色板的數據結構定義。
表5-4列出了tagRGBTRIPLE中各字段的含義。 表5-4 tagRGBTRIPLE結構
4.位圖數據(bitmap-data) 如果圖像是單色、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壓縮算 法壓縮。 RLE4是壓縮16色圖像數據的,RLE4采用表5-5所示方式壓縮數據。 表5-5 RLE4壓縮方法
假設有如下16色位圖數據,共20字節,數據使用了RLE4壓縮:
數據解壓時首先讀取05,因為05不等于0,所以選擇A方案,根據A方案,05表示后面數據重復的次數,接著讀取00,00表示有兩個顏色索引,每 個索引占4位,第一個像素在高4位,第二個像素在低4位,即在一個字節中低像素在高位,高像素在低位。05 00解壓后等于00 00 0。 讀取04,選擇A方案,按照上面的操作解析,04是后面數據重復的次數,05是兩個顏色索引,第3個顏色索引為5,第4個顏色索引為0。04 05解壓后等于05 05。 讀取00,選擇B方案,讀取08,08表示后面有效的顏色索引數。00 08解壓后等于09 05 04 00。 讀取04,選擇A方案,按照上面的操作解析,04是后面數據重復的次數,05是兩個顏色索引。04 05解壓后等于05 05。 讀取08,選擇A方案,按照上面的操作解析,08是后面數據重復的次數,09是兩個顏色索引。08 09解壓后等于09 09 09 09。? 讀取07,選擇A方案,按照上面的操作解析,07是后面數據重復的次數,01是兩個顏色索引。07 01解壓后等于01 01 01 0。 讀取00,選擇B方案,讀取00,00表示后面有效的顏色索引數,0表示無,即解壓完一行數據。 綜合上面的操作,解壓后的數據為:
看上去和原來的數據大小一樣,沒有體現到壓縮效果,這是因為上面的例子只選擇了20字節數據,而且這20字節數據中重復的數據不多,使用RLE壓縮 重復數據不多的數據時,有時可能壓縮后的大小反而比原來的數據還大。其實一般情況下當數據比較多而且重復的時候,使用RLE壓縮效果還是比較理想的。 RLE8的壓縮方式可以參考上面的RLE4解壓方法,惟一的區別是RLE8使用1個字節存放顏色索引,而RLE4使用4位存放顏色索引。 結合上面對BMP文件的分析,下面分別對256色和24位色的BMP圖像進行十六進制分析,通過在十六進制編輯器中分析文件結構,能夠增加分析文件 的經驗。 如圖5-1和圖5-2所示,分別為256色BMP圖像cat2.bmp和24位色BMP圖像cat1.bmp。其中cat2.bmp圖像的分辨率為 200×153,文件大小為31 680字節。cat1.bmp圖像的分辨率為200×150,文件大小為90 056字節。
現 在來分析cat2.bmp的圖像文件,在Winhex中打開cat2.bmp,如圖5-3所示。
首先分析位圖文件頭的結構,如圖5-4所示。根據 BMP文件的位圖文件頭結構定義分析出cat2.bmp圖像的位圖文件頭中各字段的含義,如表5-6所示。
表5-6 cat2.bmp圖像文件中位圖文件頭各字段的含義
|
繼續分析接下來的數據,根據BMP文件結構的定義,接下來的數據是位圖信息頭,cat2.bmp圖像文件的位圖信息頭的內容如圖5-5所示。
|
(點擊查看大圖)圖5-5? cat2.bmp圖像的位圖信息頭(0x00000000-E ~ 0x00000030-5) |
表5-7所示為cat2.bmp圖像文件中位圖信息頭各字段的含義。
表5-7 cat2.bmp圖像文件中位圖信息頭各字段的含義
十六進制值 | 描 述 |
28 00 00 00: | cat2.bmp圖像的位圖信息頭大小 |
C8 00 00 00 | 00 00 00 C8 = 200,是cat2圖像的寬度,單位像素 |
99 00 00 00 | 00 00 00 99 = 153,是cat2圖像的高度,單位像素 |
01 00 | 總是1 |
08 00 | 00 08 = 8,cat2圖像的色深,即2的8次冪等于256色 |
00 00 00 00 | 壓縮方式,0表示不壓縮 |
8A 77 00 00 | 00 00 77 8A = 30602,是cat2圖像的圖像數據大小,單位字節 |
12 0B 00 00 | 00 00 0B 12 = 2834,cat2圖像的水平分辨率,單位像素/m |
12 0B 00 00 | 00 00 0B 12 = 2834,cat2圖像的垂直 分辨率,單位像素/m |
00 00 00 00 | cat2圖像使用的顏色數,0表示使用全部顏色 |
00 00 00 00 | cat2圖像中重要的顏色數,0表示所有顏色都重要 |
繼續分析接下來的數據,根據BMP文件結構的定義,因為cat2.bmp圖像是256色的位圖,所以應該有256個調色板,每個調色板占4字節,整 個調色板一共1024字節大小。 cat2.bmp圖像文件的調色板數據如圖5-6和圖5-7所示。
|
(點擊查看大圖)圖5-6? cat2.bmp圖像的調色板地址從00000036h開始存儲 |
|
(點擊查看大圖)圖5-7? cat2.bmp圖像的調色板數據結束地址是00000435h |
從圖5-6和圖5-7中可以看出,cat2.bmp圖像的調色板地址從00000036h開始到00000435h結束,即00000435h - 00000036h + 1 =400h = 1024 bytes。
如果想查看cat2圖像的調色板對應的實際顯示顏色,可以使用Adobe Photoshop CS打開cat2.bmp,在Adobe Photoshop CS的菜單欄中選擇"圖像"→"模式"→"顏色表",即可觀看cat2的調色板,如圖5-8所示。
|
圖5-8? 在Adobe Photoshop CS中查看cat2的調色板(16 X 16 ) |
圖5-8所示cat2.bmp的調色板顏色和圖5-6中的十六進制數據是一一對應的。在Adobe Photoshop CS的調色板上單擊任何一個像素的顏色即可彈出一個拾色器對話框顯示該像素顏色的詳細組成信息。cat2.bmp調色板和cat2.bmp的十六進制數據 的對應關系如圖5-9所示。
繼續分析接下來的數據,根據BMP文件結構的定義,如果一個圖像有調色板,那么緊跟在調色板后面的是圖像的數據,這些數據不是實際的顏色值,而是指 向調色板數組的索引,根據索引來獲取調色板中的顏色,如圖5-10所示。
|
(點擊查看大圖)圖5-9? cat2.bmp調色板和cat2.bmp的十六進制數據的對應關系 |
|
(點擊查看大圖)圖5-10? cat2.bmp的圖像數據 |
因為cat2.bmp是256色的位圖,即采用了8位色深作為指向調色板數組的索引,所以根據圖5-10中顯示的數據可以得知:49 49 49 B1 49 49 49 49 49 99。表示cat2.bmp位圖左下角第1個像素的顏色等于調色板[49];第2個像素的顏色等于調色板[49] ;第3個像素的顏色等于調色板[49] ;第4個像素的顏色等于調色板[B1];第5個像素的顏色等于調色板[49] ……依此類推。
?
cat1.bmp圖像是24位色圖像,根據BMP文件結構定義得知,cat1.bmp圖像沒有調色板,圖像數據存儲的是實際的顏色數據,每個像素用 3字節表示,分別是紅綠藍。由于cat1.bmp和cat2.bmp的位圖文件頭和位圖信息頭結構一樣,所以cat1.bmp的位圖文件頭和位圖信息頭可 以參考上面對cat2.bmp的分析,下面從cat1.bmp的位圖信息頭結束的位置開始分析,如圖5-11所示。
|
(點擊查看大圖)圖5-11? cat1.bmp圖像的圖像數據((24位色BMP圖像cat1.bmp,分辨率為200×150,文件大小為90 056字節)) |
從圖5-11可以看到表示每個像素的紅綠藍三色的值,實際存放的時候是倒過來存放的,在分析BMP圖像格式時需要注意這點。
通過上面對BMP文件存儲結構的分析發現,BMP文件的位圖文件頭和位圖信息頭存在著大量的重復數據。如果存儲大量同一色深的BMP位圖,必然會浪 費大量存儲空間,所以很多時候游戲編程人員都會去掉BMP文件頭和信息頭,只保留幾個必要的信息和圖像數據,那么BMP文件頭和信息頭中哪幾個字段是必須 保留的呢?
使用Winhex的文件比較功能比較兩個24位色深的BMP圖像文件,觀察兩個文件的文件頭和信息頭有什么不同的地方,如圖5-12所示。
|
(點擊查看大圖)圖5-12? 使用Winhex比較兩個24位色深的BMP圖像文件 |
從圖5-12可以看出,兩個色深相同的BMP圖像的文件頭和信息頭一共有4處不同的地方,分別是文件頭的文件大小、信息頭的圖像寬度、圖像高度和圖 像數據大小。
所以很多時候,游戲編程人員只保留圖像文件的文件大小、圖像寬度、圖像高度和圖像數據大小信息,甚至有時不需要保留文件大小這個數值,使用圖像數據大小數值即可。
在分析未知文件存儲格式時,如果遇到去掉了文件頭的文件時,如上面所說的BMP文件,會給分析未知文件格式帶來一定的困難。這時需要使用十六進制編 輯器的文件比較功能,觀察兩個同類的未知文件格式尋找某些潛在的規律,如果實在觀察不出規律的,那只能使用白盒分析方法,對調用此未知文件格式的程序進行反匯編跟蹤調試了。當然,有時靈感和運氣也很重要。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
from:https://www.cnblogs.com/glegoo/archive/2012/09/28/2707851.html
位圖文件大小的精準計算方法
?? 8位(bit)位圖:彩色版中有2^8=256種顏色,具體哪256種顏色可由調色板靈活規定,因此每個像素點最多有256種情況(顏色),故剛好可用兩位十六進制碼(16^2=256)表示,占1字節。
一幅512×512的8位位圖大小計算方法:位圖文件頭(14字節00000000h開始到0000000Dh)+位圖信息頭(40字節0000000Eh開始到00000035h)+調色板(256×彩色表4字節 00000036h開始到00000435h)+實際像素點占內存(512×512×1字節)=263 222字節(Byte)。
????? 24位位圖:又名RGB真彩色圖,含2^24=16 777 216=16M色,沒有彩色表,原因上文已說明。每個像素點由3個字節(十六進制碼6位)表示,每個字節負責控制一種顏色,分別為藍(Blue)、綠(Green)、紅(Red)。為什么每種顏色用1個字節控制呢?我們知道,圖像中任何顏色都是由藍、綠、紅混合而成,而在24位位圖中這三種顏色的跨度(深度)分別為256=2^8,占二進制8bit=1字節,故藍、綠、紅剛好可用1個字節表示。那么每個像素點可能的顏色就有256×256×256=2^24種。
一幅256×256的24位位圖大小計算方法:位圖文件頭(14字節00000000h開始到0000000Dh)+位圖信息頭(40字節0000000Eh開始到00000035h)+實際像素點占內存(256×256×3字節)=196 662字節(Byte)。 ???
需要注意的是,Windows有“補零”的習慣!即要求位圖的每一行像素所占字節數必須被4整除。若不能倍4整除,則在該位圖每一行的十六進制碼末尾“補”1至3個字節的“00”。
例如:一幅寬253×高256的24位位圖,微軟在生成該圖為實際文件時,計算每一行像素所占字節=寬253×3字節=759字節,檢驗其被4除余1,則在每行的十六進制碼末尾加1個字節,補“00”,變為760字節。因此我們計算該圖大小時應先判斷是否“補零”,再得出算法:該圖大小=位圖文件頭(14字節)+位圖信息頭(40字節)+實際像素點占內存(高256×每行760字節)=194614字節(Byte)。 ??? 有趣的是,“補零”只針對位圖的寬進行檢驗,一幅寬256×高253的24位位圖,其大小=位圖文件頭(14字節)+位圖信息頭(40字節)+實際像素點占內存(高253×每行768字節)=194358字節(Byte)< 196 662字節(Byte)。這樣,只是把此圖像的寬和高顛倒,圖像所占內存竟然變小了。