日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

转贴:BMP格式详解 二 (转载)

發(fā)布時間:2025/3/21 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 转贴:BMP格式详解 二 (转载) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

http://www.360doc.com/content/10/1107/14/1188581_67355279.shtml

調色板

當bpp小于等于8時,BMP使用調色板記錄色彩信息,調色板中每條數(shù)據(jù)(即每種色彩值)都是一個uint型數(shù)據(jù)。當調色板存在時,圖像數(shù)據(jù)塊中存 儲的只是各個像素的色彩在調色板中的索引值,必須通過在調色板中查表,才能獲知各個像素的真實顏色。若引入調色板,則調色板數(shù)據(jù)塊緊隨在圖像參數(shù)數(shù)據(jù)塊之 后。

當bpp == 1時,調色板合法索引值只有0和1。因此調色板中只有2個色彩值,分別表示索引值為0和1時的色彩信息。

當bpp == 4或bpp == 8時,合法索引值范圍擴大為[0,15]和[0,255]。但圖像中不一定使用到了全部16種或256種顏色。第47-50字節(jié)存儲的uint型數(shù)據(jù)指出 圖像中實際應用的色彩數(shù),也即調色板中的色彩值數(shù)目。當然,它不應超出調色板的合法索引值的范圍。

當bpp == 4或bpp == 8時,可以采用Run-Length-Encoding方式壓縮圖像的存儲空間,即壓縮方式選項的值為1或2(當選項值為0時,不壓縮)。這種編碼格式所 考慮的情況是,若4bpp或8bpp位圖的尺寸較大時,由于色彩總數(shù)非常有限,所以圖像中必然會有很多顏色重復的像素。因此BMP圖像格式的設計者決定采 取一個簡單的措施來挽回一些被浪費掉的存儲空間。這個簡單的措施就是RLE壓縮方法。

RLE, Run-Length-Encoding

如果你是一個有優(yōu)化癖的程序員,當你發(fā)現(xiàn)一張8bpp、寬300像素的位圖中有一行像素只有兩種顏色:前100個像素是紅色,后200個像素是藍 色,然而你的位圖卻忠實地用100字節(jié)來存儲前半行重復的紅色,又用200字節(jié)來存儲后半行重復的藍色,那么你一定會抓狂到大罵BMP格式的設計者是白 癡。

為了避免被罵,BMP格式的設計者想出了這樣的辦法:先用一個字節(jié)來存儲重復色彩的數(shù)量,再用一個字節(jié)來存儲這個色彩的值,即用兩個字節(jié)代表一段顏 色重復的像素。并且,他們給重復色彩的數(shù)量起了個名字,叫做Run-Length,可能是因為只有在運行時我們才能知道這段重復色彩的長度。由于 runlength為0時沒有意義,因此設計者把runlength=0當做每行的終止符。于是,同樣存儲一行300個像素,原先需要300字節(jié),現(xiàn)在只 用5個字節(jié)就搞定!

字節(jié)

1

2

3

4

5

內容

100

red

200

blue

0

由于你是一個有著嚴重優(yōu)化癖的程序員,所以你對這樣粗制濫造的優(yōu)化方法并不滿足,因為你很快發(fā)現(xiàn),如果一張位圖中沒有連續(xù)重復的像素(例如紅藍像素 點陣),那么用剛才發(fā)明的這個辦法存儲300個像素,居然要用601字節(jié)!當然,這種情況下最好的辦法是不用壓縮算法。可是,如果既有重復像素,又有點陣 的情況呢?比如前150像素是重復的綠色,后150像素是紅藍相間的像素點陣。

為了滿足你變態(tài)的優(yōu)化癖,BMP格式的設計者只好繼續(xù)發(fā)展這個算法。首先,他們保留了“用一個字節(jié)來存儲重復色彩的數(shù)量,再用一個字節(jié)來存儲這個色 彩的值”的設計思路,然后修改了runlength為0的含義。設計者規(guī)定,當遇到runlength==0時,我們要繼續(xù)讀取下一個字節(jié),若該字節(jié)值為 n,意味著后面的n個像素將采用“逐字翻譯”的方式來解析,也就是說,這n個像素的前面沒有runlength這個字節(jié)。用這種方法壓縮“前150像素是 重復的綠色,后150像素是紅藍相間的像素點陣”的300個像素,只需要154個字節(jié)。

字節(jié)

1

2

3

4

后150個字節(jié)

內容

150

green

0

150

red,blue,…,red,blue

這個近似完美的結果中有個小問題:設計BMP格式的天才們把runlength==0的含義修改后,我們就沒有行終結符了。不過天才終歸是天才,他 們發(fā)現(xiàn)“逐字翻譯”的像素數(shù)必須大于2才有意義(想想這是為什么?),因此runlength==0之后的那個字節(jié)的值為0、1或2時,目前還沒有意義。 于是天才們規(guī)定,當這個值為0時,表示行結束符;當這個值為1時,表示文件結束符;當這個值為2時,似乎仍然沒有什么意義;只有當該值大于等于3時,才是 “逐字翻譯”。完整的壓縮結果是:

字節(jié)

1

2

3

4

后150個字節(jié)

155

156

內容

150

green

0

150

red,blue,…,red,blue

0

0

這就是傳說中的Run-Length-Encoding for 8bpp。4bpp的RLE跟8bpp時沒有本質差別。

RGBBit-Fields

當圖像中引用的色彩超過256種時,我們就需要16bpp或更高bpp的位圖。調色板不適合bpp較大的位圖,因此16bpp以上的位圖都不使用調色板。不使用調色板的位圖圖像有兩種編碼格式:RGB和Bit-Fields(下稱BF)。

RGB編碼格式是一種均分的思想,使Red、Green、Blue三個顏色分量所包含的信息容量盡可能一樣大。

16bpp-RGB:在每個像素所占的16bits中,低5位表示Blue分量;中5為表示Green分量;高5位表示Red分量;最高1位無意義 (后來有些應用程序將其視為透明度Alpha分量,但這并不是標準)。所以從低到高的順序實際上是B-G-R,這也是我在BMP簡介的表格里,把RGB的 編碼方式都寫成BGR的原因。

24bpp-RGB:24bpp的位圖又稱為真彩位圖,它通常只有這一種編碼格式,在24bits中,低8位表示Blue分量;中8為表示Green分量;高8位表示Red分量。

32bpp-RGB:在32bits中,低24位的編碼方式與24bpp位圖相同,最高8位用來表示透明度Alpha分量。32bpp的位圖尺寸太大,一般只有在圖像處理的中間過程中使用。對于需要半透過效果的圖像,更好的選擇是PNG格式。

BF編碼格式與RGB不同,它利用位域操作,人為地確定RGB三分量所包含的信息容量。在圖像參數(shù)信息模塊的介紹中提及,當壓縮方式選項置為BF 時,圖像參數(shù)結構體將比平時多出16字節(jié)。這16字節(jié)實際上是4個dword的位域掩碼。按照先后順序,它們分別是R、G、B、A四個分量的位域掩碼。當 然如果沒有Alpha分量,則Alpha掩碼沒有實際意義。

位域掩碼的作用是:指出像素色彩值中RGB分量,就像子網(wǎng)掩碼指出子網(wǎng)網(wǎng)段一樣。

16bpp-BF-565:這是BF編碼格式最著名和最普遍的應用。它的Red、Green和Blue分量的位域掩碼分別是0xF800、0x07E0和0x001F。

我們平時所能夠見到的位圖中使用BF編碼格式的并不多,因為它看上去比較麻煩,而效果也不見得比RGB要好(你能用肉眼分辨出16bpp-RGB和16bpp-BF-565之間的區(qū)別嗎?)。

BF編碼格式的重要應用在于游戲軟件。游戲軟件通常包含數(shù)量龐大的小尺寸圖片。如果一張圖片中幾乎沒有Blue分量,那么使用16bpp-RGB格 式顯然會浪費掉B分量所占的5位。此時若采用16bpp-BF-772格式,只給B分量2位,那么R與G分量都擁有7位的容量,幾乎接近真彩圖像。因此存 儲空間小、仿真彩能力強的特點使BF編碼格式仍然有著獨特的用武之地。

32bpp-BF-xxx:我一直不明白為什么會存在32bpp的位圖。如果說32bpp-RGB格式的存在是因為在圖像處理過程中存儲起來比較高效(不用壓縮),那么32bpp-BF又是為什么存在呢?

圖像數(shù)據(jù)塊

圖像數(shù)據(jù)塊從文件頭中起始偏移量字段所指出的位置開始,其中存放著位圖圖像的數(shù)據(jù),數(shù)據(jù)格式由圖像參數(shù)信息塊中的壓縮方式選項的取值決定。操作圖像數(shù)據(jù)塊時,有一些注意事項:

當壓縮方式為RGB時,圖像數(shù)據(jù)塊以“行”為單位雙字對齊。例如一張寬度為5像素的8bpp的圖像,其實際使用的存儲空間是每行8個字節(jié)。又如一幅4bpp、寬度為5像素的位圖圖像,其實際使用的存儲空間是每行4個字節(jié)。

當bpp < 8時,每個字節(jié)將存放多個像素的色彩索引,則先出現(xiàn)的像素存放在高位中。例如某4bpp圖像第一行像素的順序是red, green, blue, yellow, …則圖像數(shù)據(jù)塊中第一個字節(jié)的高4位值為red,低4位值為green;第二字節(jié)高4位值為blue,低4位值為yellow。1bpp時的情況以此類 推。

還記得前面提到,圖像參數(shù)里,高度有可能是負值嗎?這看上去很逗,但事實是,你見過的大多數(shù)位圖,其圖像參數(shù)里的高度都是負值。BMP格式設計者規(guī) 定,當高度為正值時,圖像數(shù)據(jù)塊中記錄的第一行像素數(shù)據(jù)是圖像的最后一行;而數(shù)據(jù)塊中最后一行數(shù)據(jù)才是實際圖像的第一行,也就是說,數(shù)據(jù)塊中的行記錄與實 際圖像反序。而當高度為負值時,數(shù)據(jù)塊中的行記錄與實際圖像才是同序的。

如果你覺得這太奇怪了,我很理解。不過我們必須懷著無比崇敬之情接受這個看似滑稽的規(guī)定。這是因為在那個年代里,那些設計BMP格式的天才首先都是 數(shù)學家,讓天才的數(shù)學家們習慣左上角為原點,并且y軸方向向下的二維直角坐標系的格局顯然是很困難的,既然他們手上又有設計BMP的大權,于是……唉,這 就是歷史。

轉載于:https://blog.51cto.com/jkers/677107

總結

以上是生活随笔為你收集整理的转贴:BMP格式详解 二 (转载)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。