bitmap格式分析

2022-08-13 07:24:15 字數 4372 閱讀 6076

**:

最近正在著手開發乙個庫,也就是實現對常見格式的度寫操作。作為總結與積累,我會把這些格式以及載入的實現寫在我的

blog

上。說到,位圖(

bitmap

)當然是最簡單的,它

windows

顯示的基本格式,其擴充套件名為

*.bmp

。在windows

flash

中使用了適量圖,是按相同顏色區域儲存的)。

一、下面我們來看看位**件(

*.bmp

)的格式。

位**件主要分為如下

3個部分:

塊名稱對應

windows

結構體定義

大小(byte

)檔案資訊頭

bitmapfileheader

14點陣圖資訊頭

bitmapinfoheader

40rgb

顏色陣列

byte*

由影象長寬尺寸決定

1、 檔案資訊頭

bitmapfileheader

結構體定義如下:

typedef struct tagbitmapfileheader bitmapfileheader;

其中:bftype

說明檔案的型別,該值必需是0x4d42,也就是字元'bm'。

bfsize

說明該位**件的大小,用位元組為單位

bfreserved1

保留,必須設定為0

bfreserved2

保留,必須設定為0

bfoffbits

說明從檔案頭開始到實際的圖象資料之間的位元組的偏移量。這個引數是非常有用的,因為位圖資訊頭和調色盤的長度會根據不同情況而變化,所以你可以用這個偏移值迅速的從檔案中讀取到位資料。

2、位圖資訊頭

bitmapinfoheader

結構體定義如下:

typedef struct tagbitmapinfoheader bitmapinfoheader;

其中:bisize

說明bitmapinfoheader

結構所需要的字數。

biwidth

說明圖象的寬度,以象素為單位。

biheight

說明圖象的高度,以象素為單位。注:這個值除了用於描述影象的高度之外,它還有另乙個用處,就是指明該影象是倒向的點陣圖,還是正向的點陣圖。如果該值是乙個正數,說明影象是倒向的,如果該值是乙個負數,則說明影象是正向的。大多數的

bmp檔案都是倒向的點陣圖,也就是時,高度值是乙個正數。

biplanes

為目標裝置說明位面數,其值將總是被設為1。

bibitcount

說明位元數/象素,其值為1、4、8、16、24、或32。但是由於我們平時用到的影象絕大部分是24位和32位的,所以我們討論這兩類影象。

bicompression

說明圖象資料壓縮的型別,同樣我們只討論沒有壓縮的型別:

bi_rgb

。bisizeimage

說明圖象的大小,以位元組為單位。當用

bi_rgb

格式時,可設定為0。

bixpelspermeter

說明水平解析度,用象素

/公尺表示。

biypelspermeter

說明垂直解析度,用象素

/公尺表示。

biclrused

說明位圖實際使用的彩色表中的顏色索引數(設為

0的話,則說明使用所有調色盤項)。

biclrimportant

說明對圖象顯示有重要影響的顏色索引的數目,如果是

0,表示都重要。

3、rgb

顏色陣列

有關rgb

三色空間我想大家都很熟悉,這裡我想說的是在

windows

下,rgb

顏色陣列儲存的格式其實

bgr。也就是說,對於

24位的

rgb位影象素資料格式是:藍色b

值綠色g值

紅色r值對於

32位的

rgb位影象素資料格式是:藍色b

值綠色g值

紅色r值透明通道a值

透明通道也稱

alpha

通道,該值是該畫素點的透明屬性,取值在

0(全透明)到

255(不透明)之間。對於

24位的影象來說,因為沒有

alpha

通道,故整個影象都不透明。

二、搞清了檔案格式,下一步我們要實現載入。

載入檔案的目的是要得到屬性,以及

rgb資料,然後可以將其繪製在dc上

(gdi)

,或是生成紋理物件

(3d:opengl/direct3d)

。這兩種用途在資料處理上有點區別,我們主要按前一種用法講,在和

3d有不同的地方,我們再提出來。

1、載入檔案頭

//load the file header

bitmapfileheader header;

memset(&header, 0, sizeof(header));

inf.read((char*)&header, sizeof(header));

if(header.bftype != 0x4d42)

return false;

這個很簡單,沒有什麼好說的。

2、載入位圖資訊頭

//load the image information header

bitmapinfoheader infoheader;

memset(&infoheader, 0, sizeof(infoheader));

inf.read((char*)&infoheader, sizeof(infoheader));

m_iimagewidth = infoheader.biwidth;

m_iimageheight = infoheader.biheight;

m_ibitsperpixel = infoheader.bibitcount;

這裡我們得到了

3各重要的圖形屬性:寬,高,以及每個畫素顏色所占用的位數。

3、行對齊

由於windows

在進行行掃瞄的時候最小的單位為

4個位元組,所以當寬x

每個畫素的位元組數

!= 4

的整數倍

時要在每行的後面補上缺少的位元組,以

0填充(一般來說當影象寬度為2x

高x每個畫素的位元組數

了,我們需要通過下面的方法計算正確的資料長度:

//calculate the image data size

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

m_iimagedatasize = ilinebytecnt * m_iimageheight;

4、載入資料

對於24

位和32

位的位**件,位圖資料的偏移量為

sizeof(bitmapfileheader)

+ sizeof(bitmapinfoheader)

,也就是說現在我們可以直接讀取影象資料了。

if(m_pimagedata) delete m_pimagedata;

m_pimagedata = new unsigned char[m_iimagedatasize];

inf.read((char*)m_pimagedata, m_iimagedatasize);

如果你足夠細心,就會發現記憶體

m_pimagedata

裡的資料的確是

bgr格式,可以用個純藍色或者是純紅色的測試一下。

5、繪製

好了,資料和屬性我們都有了,現在就可以拿來隨便用了,就和吃饅頭一樣,愛粘白糖粘白糖,愛粘紅糖粘紅糖。下面是我的

gdi繪製**,僅作參考。

void cimage::drawimage(hdc hdc, int ileft, int itop, int iwidth, int iheight)

6、3d(opengl)

的不同之處

如果你是想用剛才我們得到的資料生成紋理物件,那麼你還要請出下面的問題。

首先,用來生成紋理的資料不需要對齊,也就是說不能在每行的後面加上對齊的位元組。當然在

opengl

裡要求紋理的尺寸為

2的冪,所以這個問題實際上不存在;

其次,我們得到的圖形資料格式是

bgr(bgra)

,所以在生成紋理的時候,需指定格式為

gl_bgr_ext(gl_bgra_ext)

;否則需要做

bgr->rgb(bgra->rgba)

的轉化。

bitmap格式分析

最近正在著手開發乙個庫,也就是實現對常見格式的度寫操作。作為總結與積累,我會把這些格式以及載入的實現寫在我的blog上。一 下面我們來看看位 件 bmp 的格式。位 件主要分為如下3個部分 塊名稱對應windows結構體定義 大小 byte 檔案資訊頭 bitmapfileheader 14 位圖資...

bitmap格式分析

一 下面我們來看看位 件 bmp 的格式。位 件主要分為如下3個部分 塊名稱對應windows結構體定義 大小 byte 檔案資訊頭 bitmapfileheader 14 位圖資訊頭 bitmapinfoheader 40 rgb顏色陣列 byte 由影象長寬尺寸決定 1 檔案資訊頭bitmapf...

BitMap格式詳解。

bmp檔案由以下四部分構成 位 件頭 包含了影象型別,影象大小,影象資料存放的位置 即位圖資料的偏移 和 兩個保留字段。格式定義如下 typedef struct tagbitmapfileheader bitmapfileheader,far lpbitmapfileheader,pbitmapf...