您好,登錄后才能下訂單哦!
什么是BMP?
BMP是一種與硬件設備無關的圖像文件格式,使用非常廣。它采用位映射存儲格式,除了圖像深度可選以外,不采用其他任何壓縮,因此,BblP文件所占用的空間很大。BMP文件的圖像深度可選lbit、4bit、8bit及24bit。BMP文件存儲數據時,圖像的掃描方式是按從左到右、從下到上的順序。
由于BMP文件格式是Windows環境中交換與圖有關的數據的一種標準,因此在Windows環境中運行的圖形圖像軟件都支持BMP圖像格式。
典型的BMP圖像文件由三部分組成:位圖文件頭數據結構,它包含BMP圖像文件的類型、顯示內容等信息;位圖信息數據結構,它包含有BMP圖像的寬、高、壓縮方法,以及定義顏色等信息
具體數據舉例:
如某BMP文件開頭:
BMP文件可分為四個部分:位圖文件頭、位圖信息頭、彩色板、圖像數據陣列,在上圖中已用*分隔。
一、圖像文件頭
1)1:圖像文件頭。424Dh=”BM”,表示是Windows支持的BMP格式。
2)2-3:整個文件大小。4690 0000,為00009046h=36934。
3)4-5:保留,必須設置為0。
4)6-7:從文件開始到位圖數據之間的偏移量。4600 0000,為00000046h=70,上面的文件頭就是35字=70字節。
5)8-9:位圖圖信息頭長度。
6)10-11:位圖寬度,以像素為單位。8000 0000,為00000080h=128。
7)12-13:位圖高度,以像素為單位。9000 0000,為00000090h=144。
8)14:位圖的位面數,該值總是1。0100,為0001h=1。
二、位圖信息頭
9)15:每個像素的位數。有1(單色),4(16色),8(256色),16(64K色,高彩色),24(16M色,真彩色),32(4096M色,增強型真彩色)。1000為0010h=16。
10)16-17:壓縮說明:有0(不壓縮),1(RLE 8,8位RLE壓縮),2(RLE 4,4位RLE壓縮,3(Bitfields,位域存放)。RLE簡單地說是采用像素數+像素值的方式進行壓縮。T408采用的是位域存放方式,用兩個字節表示一個像素,位域分配為r5b6g5。圖中0300 0000為00000003h=3。
11)18-19:用字節數表示的位圖數據的大小,該數必須是4的倍數,數值上等于位圖寬度×位圖高度×每個像素位數。0090 0000為00009000h=80×90×2h=36864。
12)20-21:用象素/米表示的水平分辨率。A00F 0000為0000 0FA0h=4000。
13)22-23:用象素/米表示的垂直分辨率。A00F 0000為0000 0FA0h=4000。
14)24-25:位圖使用的顏色索引數。設為0的話,則說明使用所有調色板項。
15)26-27:對圖象顯示有重要影響的顏色索引的數目。如果是0,表示都重要。三、彩色板 (非必有)
16)28-35:彩色板規范。對于調色板中的每個表項,用下述方法來描述RGB的值:
1字節用于藍色分量
1字節用于綠色分量
1字節用于紅色分量
1字節用于填充符(設置為0)
對于24-位真彩色圖像就不使用彩色板,因為位圖中的RGB值就代表了每個象素的顏色。
如,彩色板為00F8 0000 E007 0000 1F00 0000 0000 0000,其中:
00FB 0000為FB00h=1111100000000000(二進制),是紅色分量的掩碼。
E007 0000為 07E0h=0000011111100000(二進制),是綠色分量的掩碼。
1F00 0000為001Fh=0000000000011111(二進制),是紅色分量的掩碼。
0000 0000總設置為0。
將掩碼跟像素值進行“與”運算再進行移位操作就可以得到各色分量值。看看掩碼,就可以明白事實上在每個像素值的兩個字節16位中,按從高到低取5、6、5位分別就是r、g、b分量值。取出分量值后把r、g、b值分別乘以8、4、8就可以補齊第個分量為一個字節,再把這三個字節按rgb組合,放入存儲器(同樣要反序),就可以轉換為24位標準BMP格式了。
四、圖像數據陣列
17)17-...:每兩個字節表示一個像素。陣列中的第一個字節表示位圖左下角的象素,而最后一個字節表示位圖右上角的象素。
下面用winhex打開一個bmp文件,察看其16進制數據。
一個bmp文件以BITMAPFILEHEADER結構體開始,BITMAPFILEHEADER的第1個屬性是bfType(2字節),這里恒定等于0x4D42。由于內存中的數據排列高位在左,低位在右,所以內存中從左往右看就顯示成(42 4D),所以在winhex中頭兩個 字節顯示為(42 4D)就是這樣形成的,以后的數據都是這個特點,不再作重復說明。
1、BITMAPFILEHEADER的第2個屬性是bfSize(4字節),表示整個bmp文件的大小,這里等于0x000004F8=1272字節。
2、BITMAPFILEHEADER的第3個、第4個屬性分別是bfReserved1、bfReserved2(各2字節),這里是2個保留屬性,都為0,這里等于&H0000、0×0000。
3、BITMAPFILEHEADER的第5個屬性是bfOffBits(4字節),表示DIB數據區在bmp文件中的位置偏移量,這里等于0×00000076=118,表示數據區從文件開始往后數的118字節開始。
4、BITMAPFILEHEADER結構體這里就講完了,大家會發現BITMAPFILEHEADER只占了bmp文件開始的14字節長度,但需要 特別說明的是在vb中定義一個BITMAPFILEHEADER結構體變量,其長度占了16個字節,原因就是第1個屬性本來應該只分配2個字節,但實際被 分配了4個字節,多出來2個字節,所以如果想保存一張bmp圖片,寫入BITMAPFILEHEADER結構體時一定要注意這一點。
接下來是BITMAPINFO結構體部分。BITMAPINFO段由兩部分組成:BITMAPINFOHEADER結構體和RGBQUAD結構 體。其中RGBQUAD結構體表示圖片的顏色信息,有些時候可以省略,一般的24位圖片和32位圖片都不帶RGBQUAD結構體,因為DIB數據區直接表 示的RGB值,一般4位圖片和8位圖片才帶有RGBQUAD結構體。(多少位的圖片就是用多少位來表示一個顏色信息,例如4位圖片表示用4個bit來表示 一個顏色信息。)一個bmp文件中有沒有RGBQUAD結構體,可以根據前面BITMAPFILEHEADER結構體的第5個屬性bfOffBits來判 斷,因為BITMAPINFOHEADER結構體長度為40bit,如果BITMAPINFOHEADER結構體結束后還未到DIB數據區的偏移量,就說 明接下來的數據是RGBQUAD結構體部分。這里講的C:\WINDOWS\Blue Lace 16.bmp是一個4bit圖片,所以它帶有 RGBQUAD結構體。
下面進入正題BITMAPINFOHEADER部分。
1、BITMAPINFOHEADER的第1個屬性是biSize(4字節),表示BITMAPINFOHEADER結構體的長度,最常見的長度是40字節,UltraEdit中可以看到緊接著的4個字節等于0×00000028=40字節。
2、BITMAPINFOHEADER的第2個屬性是biWidth(4字節),表示bmp圖片的寬度,這里等于0×00000030=48像素。
3、BITMAPINFOHEADER的第3個屬性是biHeight(4字節),表示bmp圖片的高度,這里等于0×00000030=48像素。
4、BITMAPINFOHEADER的第4個屬性是biPlanes(2字節),表示bmp圖片的平面屬,顯然顯示器只有一個平面,所以恒等于1,這里等于0×0001。
5、BITMAPINFOHEADER的第5個屬性是biBitCount(2字節),表示bmp圖片的顏色位數,即24位圖、32位圖等等。這里等于0×0004,表示該圖片為4位圖。
6、BITMAPINFOHEADER的第6個屬性是biCompression(4字節),表示圖片的壓縮屬性,bmp圖片是不壓縮的,等于0,所以這里為0×00000000。
7、BITMAPINFOHEADER的第7個屬性是biSizeImage(4字節),表示bmp圖片數據區的大小,當上一個熟悉biCompression等于0時,這里的值可以省略不填,所以這里等于0×00000000。
8、BITMAPINFOHEADER的第8個屬性是biXPelsPerMeter(4字節),表示圖片X軸每米多少像素,可省略,這里等于0x00000EC3=3779像素/米。
9、BITMAPINFOHEADER的第9個屬性是biYPelsPerMeter(4字節),表示圖片Y軸每米多少像素,可省略,這里等于0x00000EC3=3779像素/米。
10、BITMAPINFOHEADER的第10個屬性是biClrUsed(4字節),表示使用了多少個顏色索引表,一般biBitCount屬性小于16才會用到,等于0時表示有2^biBitCount個顏色索引表,所以這里仍等于0×00000000。
11、BITMAPINFOHEADER的第11個屬性是biClrImportant(4字節),表示有多少個重要的顏色,等于0時表示所有顏色都很重要,所以這里等于0×00000000。
至此BITMAPINFOHEADER結構體結束。
由于這個圖片到這里還未到達DIB數據區的偏移量,所以接下來的部分是RGBQUAD結構體。RGBQUAD結構體由4個字節型數據組成,所以一 個RGBQUAD結構體只占用4字節空間,從左到右每個字節依次表示(藍色,綠色,紅色,未使用)。舉例的這個圖片我數了數總共有16個RGBQUAD結 構體,由于該圖片是4位圖,2^4正好等于16,所以它把16種顏色全部都枚舉出來了,這些顏色就是一個顏色索引表。顏色索引表編號從0開始,總共16個 顏色,所以編號為0-15。從winhex中可以看到按照順序,這16個RGBQUAD結構體依次為:
編號:(藍,綠,紅,空)
0號:(00,00,00,00)
1號:(00,00,80,00)
2號:(00,80,00,00)
3號:(00,80,80,00)
4號:(80,00,00,00)
5號:(80,00,80,00)
6號:(80,80,00,00)
7號:(80,80,80,00)
8號:(C0,C0,C0,00)
9號:(00,00,FF,00)
10號:(00,FF,00,00)
11號:(00,FF,FF,00)
12號:(FF,00,00,00)
13號:(FF,00,FF,00)
14號:(FF,FF,00,00)
15號:(FF,FF,FF,00)
到這里,正好滿足DIB數據區的偏移量,所以后面的字節就是圖片內容了。這里需要提醒的是所有的DIB數據掃描行是上下顛倒的,也就是說一幅圖片先繪制底部的像素,再繪制頂部的像素,所以這些DIB數據所表示的像素點就是從圖片的左下角開始,一直表示到圖片的右上角。
由于這里的圖片是4位圖片,也就是說4bit就表示一個像素,一個字節有8個bit,所以一個字節能表示2個像素。
從winhex中可以看到,DIB數據區第一個字節是0×44,16進制正好是將2進制數每4個一組書寫的,跟4bit圖片正好吻 合,所以0×44表示兩個像素,高位的4表示第一個像素,低位的4表示第二個像素。這里的4不是表示RGB顏色,而是表示顏色索引號為4,由于索 引號從0開始編號的,所以4表示索引表中第5個顏色,從附圖中可以看到索引號為4的是藍色。這是第一字節,表示的是圖片左下角開始2個像素,如果有 PhotoShop打開這個圖片可以看到,左下角2個像素取出來的顏色RGB值正好等于索引表中第5個顏色的RGB值。后面的DIB數據以此類推。
至此一個bmp圖片就全部解析完了,根據這些信息就可以完整的繪制一張bmp圖片來。當然也可以簡單手工修復一個破壞不算嚴重的BMP文件!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。