BMP檔案格式詳解

2021-03-04 09:44:39 字數 4858 閱讀 4155

bmp檔案格式,又稱為bitmap(位圖)或是dib(device-independent device,裝置無關位圖),是windows系統中廣泛使用的影象檔案格式。由於它可以不作任何變換地儲存影象畫素域的資料,因此成為我們取得raw 資料的重要**。windows的圖形使用者介面(graphical user inte***ces)也在它的內建影象子系統gdi中對bmp格式提供了支援。

下面以notepad++為分析工具,結合windows的點陣圖資料結構對bmp檔案格式進行乙個深度的剖析。

bmp檔案的資料按照從檔案頭開始的先後順序分為四個部分:

bmp檔案頭(bmp file header):提供檔案的格式、大小等資訊

位圖資訊頭(bitmap information):提供影象資料的尺寸、位平面數、壓縮方式、顏色索引等資訊

調色盤(color palette):可選,如使用索引來表示影象,調色盤就是索引與其對應的顏色的對映表

位圖資料(bitmap data):就是影象資料啦^_^

下面結合windows結構體的定義,通過乙個表來分析這四個部分。

我們一般見到的影象以24位影象為主,即r、g、b三種顏色各用8個bit來表示,這樣的影象我們稱為真彩色,這種情況下是不需要調色盤的,也就是所位圖資訊頭後面緊跟的就是位圖資料了。因此,我們常常見到有這樣一種說法:

位**件從檔案頭開始偏移54個位元組就是位圖資料了,這其實說的是24或32點陣圖的情況。這也就解釋了我們按照這種程式寫出來的程式為什麼對某些位**件沒用了。

下面針對一幅特定的影象進行分析,來看看在位**件中這四個資料段的排布以及組成。

我們使用的影象顯示如下:

這是一幅16位的位**件,因此它是含有調色盤的。

在拉出影象資料進行分析之前,我們首先進行幾個約定:

1. 在bmp檔案中,如果乙個資料需要用幾個位元組來表示的話,那麼該資料的存放位元組順序為「低位址村存放低位資料,高位址存放高位資料」。如資料0x1756在記憶體中的儲存順序為:

這種儲存方式稱為小端方式(little endian) , 與之相反的是大端方式(big endian)。對兩者的使用情況有興趣的可以深究一下,其中還是有學問的。

2.  以下所有分析均以位元組為序號單位進行。

下面我們對從檔案中拉出來的資料進行剖析:

一、 bmp檔案頭

windows為bmp檔案頭定義了如下結構體:

code highlighting produced by actipro codehighlighter (freeware)

struct tagbitmapfileheader

bitmapfileheader;

其中:對照檔案資料我們看到:

1-2  :424dh = 'bm',表示這是windows支援的點陣圖格式。有很多聲稱開頭兩個位元組必須為'bm'才是位**件,從上表來看應為開頭兩個位元組必須為'bm'才是windows位**件。

3-5  :00010436h = 66614 b = 65.05 kb,通過查詢檔案屬性發現一致。

6-9  :這是兩個保留段,為0。

a-d:00000436h = 1078。即從檔案頭到位圖資料需偏移節。我們稍後將驗證這個資料。

共有14個位元組。

二、 位圖資訊頭

同樣地,windows為位圖資訊頭定義了如下結構體:

code highlighting produced by actipro codehighlighter (freeware)

typedef

struct

tagbitmapinfoheader

bitmapinfoheader;

對照資料

檔案:0e-11:00000028h = 40,這就是說我這個位圖資訊頭的大小為40個位元組。前面我們已經說過位圖資訊頭一般有40個位元組,既然是這樣,為什麼這裡還要給乙個欄位來說明呢?

這裡涉及到一些歷史,其實位圖資訊頭原本有很多大小的版本的。我們看一下下表:

出於相容性的考慮,大多數應用使用了舊版的點陣圖資訊頭來儲存檔案。而 os/2 已經過時了,因此現在最常用的格式就僅有v3 header了。因此,我們在前面說位圖資訊頭的大小為40位元組。

12-15:00000100h = 256,影象寬為255畫素,與檔案屬性一致。

16-19:00000100h = 256,影象高為255畫素,與檔案屬性一致。這是乙個正數,說明影象資料是從影象左下角到右上角排列的。

1a-1b:0001h, 該值總為1。

1c-1d:0008h = 8, 表示每個畫素佔8個位元,即該影象共有256種顏色。

1e-21:00000000h,bi_rgb, 說明本影象不壓縮。

22-25:00000000h,影象的大小,因為使用bi_rgb,所以設定為0。

26-29:00000000h,水平解析度,預設。

2a-2d:00000000h,垂直解析度,預設。

2e-31:00000100h = 256,說明本位圖實際使用的顏色索引數為256,與1c-id得到的結論一致。

32-35:00000100h = 256,說明本位圖重要的顏色索引數為256,與前面得到的結論一致。

三、 調色盤

下面的資料就是調色盤了。前面也已經提過,調色盤其實是一張對映表,標識顏色索引號與其代表的顏色的對應關係。它在檔案中的布局就像乙個二維陣列 palette[n][4],其中n表示總的顏色索引數,每行的四個元素分別表示該索引對應的b、g、r和alpha的值,每個分量佔乙個位元組。

如不設透明通道時,alpha為0。因為前面知道,本圖有256個顏色索引,因此n = 256。索引號就是所在行的行號,對應的顏色就是所在行的四個元素。

這裡擷取一些資料來說明:

索引:(藍,綠,紅,alpha)

0號:(fe,fa,fd,00)

1號:(fd,f3,fc,00)

2號:(f4,f3,fc,00)

3號:(fc,f2,f4,00)

4號:(f6,f2,f2,00)

5號:(fb,f9,f6,00) 等等。

一共有256種顏色,每個顏色占用4個位元組,就是一共1024個位元組,再加上前面的檔案資訊頭和位圖資訊頭的54個位元組加起來一共是1078個位元組。也就是說在位圖資料出現之前一共有1078個位元組,與我們在檔案資訊頭得到的資訊:檔案頭到文圖資料區的偏移為1078個位元組一致!

四、 位圖資料

下面就是位圖資料了,每個畫素佔乙個位元組,取得這個位元組後,以該位元組為索引查詢相應的顏色,並顯示到相應的顯示裝置上就可以了。

注意:由於位圖資訊頭中的影象高度是正數,所以位圖資料在檔案中的排列順序是從左下角到右上角,以行為主序排列的。

也即我們見到的第乙個畫素60是影象最左下角的資料,第二個人畫素60為影象最後一行第二列的資料,…一直到最後一行的最後一列資料,後面緊接的是倒數第二行的第一列的資料,依此類推。

如果影象是24位或是32位資料的點陣圖的話,位圖資料區就不是索引而是實際的畫素值了。下面說明一下,此時位圖資料區的每個畫素的rgb顏色陣列排布:

24位rgb按照bgr的順序來儲存每個畫素的各顏色通道的值,乙個畫素的所有顏色分量值都存完後才存下乙個下乙個畫素,不進行交織儲存。

32位資料按照bgra的順序儲存,其餘與24位位圖的方式一樣。

畫素的排布規則與前述一致。

對齊規則

講完了畫素的排列規則以及各畫素的顏色分量的排列規則,最後我們談談資料的對齊規則。我們知道windows預設的掃瞄的最小單位是4位元組,如果資料對齊滿足這個值的話對於資料的獲取速度等都是有很大的增益的。因此,bmp影象順應了這個要求,要求每行的資料的長度必須是4的倍數,如果不夠需要進行位元填充(以0填充),這樣可以達到按行的快速訪問。

這時,位圖資料區的大小就未必是**寬×每畫素位元組數×**高能表示的了,因為每行可能還需要進行位元填充。

填充後的每行的位元組數為:

,其中bpp(bits per pixel)為每畫素的位元數。

在程式中,我們可以表示為:

int ilinebyte**t = (((m_iimagewidth * m_ibitsperpixel) + 31) >> 5) << 2;

這樣,位圖資料區的大小為:

m_iimagedatasize = ilinebyte**t * m_iimageheight;

我們在掃瞄完一行資料後,也可能接下來的資料並不是下一行的資料,可能需要跳過一段填充資料:

skip = 4 - ((m_iimagewidth * m_ibitsperpixel)>>3) & 3;

五、拾遺

至此,我們通過分析乙個具體的位**件例子詳細地剖析了位**件的組成。需要注意的是:我們講的主要是pc機上的位**件的構成,對於嵌入式平台,可能在調色盤資料段與pc機的不同。

如在嵌入式平台上常見的16位r5g6b5點陣圖實際上採用的掩模的方式而不是索引的方式來表示影象。此時,在調色盤資料段共有四個部分,每個部分為四個位元組,實際表示的是彩色版規範。即:

第乙個部分是紅色分量的掩模

第二個部分是綠色分量的掩模

第三個部分是藍色分量的掩模

第四個部分是alpha分量的掩模(預設為0)

典型的調色盤規範在檔案中的順序為為:

00f8 0000 e007 0000 1f00 0000 0000 0000

其中00f8 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就可以補齊每個分量為乙個位元組,再把這三個位元組按bgr組合,放入儲存器, 就可以轉換為24位標準bmp格式了。

消防檔案格式

單位消防基礎資料記錄 單位名稱 建檔日期年月 目錄1 單位基本情況 2 單位總平面圖 3 消防安全管理組織機構 4 重點單位及消防安全責任人 5 單位消防安全制度 6 消防設施 滅火器材基本情況 7 消防設施器材配置及管理登記明細表 8 消防設施定期檢查 檢測 維修保養記錄9 滅火和應急疏散預案 1...

消防檔案格式

單位消防基礎資料記錄 單位名稱 建檔日期年月 目錄1 單位基本情況 2 單位總平面圖 3 消防安全管理組織機構 4 重點單位及消防安全責任人 5 單位消防安全制度 6 消防設施 滅火器材基本情況 7 消防設施器材配置及管理登記明細表 8 消防設施定期檢查 檢測 維修保養記錄9 滅火和應急疏散預案 1...

投標檔案格式

報建編號 標段號 專案施工招標 投標檔案 投標人 單位公章 法定代表人或其委託 人 簽字或蓋章 年月日目錄 一 商務標 包括但不僅限於以下內容 一 投標承諾書 原件 投標函 原件 投標函附錄a 上海市建設工程施工投標標書情況彙總表 原件 投標函附錄b 原件 二 法定代表人證明 原件 授權委託書 原件...