天天看點

位圖結構

用普通方法顯示BMP位圖,占記憶體大,速度慢,在圖形縮小時,失真嚴重,在低顔色位數的裝置上顯示高顔色位數的圖形圖形時失真大。本文采用視訊函數顯示BMP位圖,可以消除以上的缺點。

一、BMP檔案結構

   1. BMP檔案組成

   BMP檔案由檔案頭、位圖資訊頭、顔色資訊和圖形資料四部分組成。

   2. BMP檔案頭

   BMP檔案頭資料結構含有BMP檔案的類型、檔案大小和位圖起始位置等資訊。

   其結構定義如下:

typedef struct tagBITMAPFILEHEADER

{

WORDbfType; // 位圖檔案的類型,必須為BM

DWORD bfSize; // 位圖檔案的大小,以位元組為機關

WORDbfReserved1; // 位圖檔案保留字,必須為0

WORDbfReserved2; // 位圖檔案保留字,必須為0

DWORD bfOffBits; // 位圖資料的起始位置,以相對于位圖

// 檔案頭的偏移量表示,以位元組為機關

} BITMAPFILEHEADER;

   3. 位圖資訊頭

   BMP位圖資訊頭資料用于說明位圖的尺寸等資訊。

typedef struct tagBITMAPINFOHEADER{

DWORD biSize; // 本結構所占用位元組數

LONGbiWidth; // 位圖的寬度,以像素為機關

LONGbiHeight; // 位圖的高度,以像素為機關

WORD biPlanes; // 目标裝置的級别,必須為1

WORD biBitCount// 每個像素所需的位數,必須是1(雙色),

// 4(16色),8(256色)或24(真彩色)之一

DWORD biCompression; // 位圖壓縮類型,必須是 0(不壓縮),

// 1(BI_RLE8壓縮類型)或2(BI_RLE4壓縮類型)之一

DWORD biSizeImage; // 位圖的大小,以位元組為機關

LONGbiXPelsPerMeter; // 位圖水準分辨率,每米像素數

LONGbiYPelsPerMeter; // 位圖垂直分辨率,每米像素數

DWORD biClrUsed;// 位圖實際使用的顔色表中的顔色數

DWORD biClrImportant;// 位圖顯示過程中重要的顔色數

} BITMAPINFOHEADER;

   4. 顔色表

   顔色表用于說明位圖中的顔色,它有若幹個表項,每一個表項是一個RGBQUAD類型的結構,定義一種顔色。RGBQUAD結構的定義如下:

typedef struct tagRGBQUAD {

BYTErgbBlue;// 藍色的亮度(值範圍為0-255)

BYTErgbGreen; // 綠色的亮度(值範圍為0-255)

BYTErgbRed; // 紅色的亮度(值範圍為0-255)

BYTErgbReserved;// 保留,必須為0

} RGBQUAD;

顔色表中RGBQUAD結構資料的個數有biBitCount來确定:

當biBitCount=1,4,8時,分别有2,16,256個表項;

當biBitCount=24時,沒有顔色表項。

位圖資訊頭和顔色表組成位圖資訊,BITMAPINFO結構定義如下:

typedef struct tagBITMAPINFO {

BITMAPINFOHEADER bmiHeader; // 位圖資訊頭

RGBQUAD bmiColors[1]; // 顔色表

} BITMAPINFO;

   5. 位圖資料

   位圖資料記錄了位圖的每一個像素值,記錄順序是在掃描行内是從左到右,掃描行之間是從下到上。位圖的一個像素值所占的位元組數:

   當biBitCount=1時,8個像素占1個位元組;

   當biBitCount=4時,2個像素占1個位元組;

   當biBitCount=8時,1個像素占1個位元組;

   當biBitCount=24時,1個像素占3個位元組;

   Windows規定一個掃描行所占的位元組數必須是4的倍數(即以long為機關),寫入位圖檔案中時也要求這樣,不足的以0填充,一個掃描行所占的位元組數計算方法:

DataSizePerline= (biWidth* biBitCount+31)/8;

// 一個掃描行所占的位元組數

DataSizePerLine= DataSizePerLine/4*4; // 位元組數必須是4的倍數

位圖資料的大小(不壓縮情況下):

DataSize= DataSizePerLine* biHeight;

二、BMP位圖一般顯示方法

   1. 申請記憶體空間用于存放位圖檔案

   GlobalAlloc(GHND,FileLength);

   2. 位圖檔案讀入所申請記憶體空間中

   LoadFileToMemory( mPBitsSrc,mFileName);

   3. 在OnPaint等函數中用建立顯示用位圖

   用CreateDIBitmap()建立顯示用位圖,用CreateCompatibleDC()建立相容DC,

   用SelectBitmap()選擇顯示位圖。

   4. 用BitBlt或StretchBlt等函數顯示位圖

   5. 用DeleteObject()删除所建立的位圖

   以上方法的缺點是: 1)顯示速度慢; 2) 記憶體占用大; 3) 位圖在縮小顯示時圖形失真大,(可通過安裝字型平滑軟體來解決); 4) 在低顔色位數的裝置上(如256顯示模式)顯示高顔色位數的圖形(如真彩色)圖形失真嚴重。

繼續閱讀