ビットマップファイル(*.bmp)のファイルフォーマットです。
ビットマップ全体の構造
BITMAPFILEHEADER
14Byte
BITMAPINFOHEADER
40Byte
カラーテーブル(無い場合もあり)
4Byte*Index数
画像データ
各構造体について
■BITMAPFILEHEADER
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;
bfType
ファイルタイプ
‘BM’
bfSize
ファイル全体のサイズ(バイト数)
bfReserved1
予約領域
常に0
bfReserved2
予約領域
常に0
bfOffBits
ファイル先頭から画像データまでのオフセット数(バイト単位)
■BITMAPINFO
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;
●BITMAPINFOHEADER
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;
biSize
構造体のサイズ
40
biWidth
画像の幅(ピクセル数)
biHeight
画像の高さ(ピクセル数)
値が負の場合、画像の上下が逆になる
biPlanes
プレーン数
常に1
biBitCount
1画素あたりのビット数
1,4,8,16,24,32
biCompression
圧縮形式
BI_RGB, BI_RLE8, BI_RLE4
BI_BITFIELDS, BI_JPEG, BI_PNG
biSizeImage
画像データのサイズ(バイト数)
BI_RGBの場合0でも可
biXPelsPerMeter
水平方向の1Mあたりの画素数
0でも可
biYPelsPerMeter
垂直方向の1Mあたりの画素数
0でも可
biClrUsed
カラーテーブルの色数
0でも可
biClrImportant
表示に必要なカラーテーブルの色数
0でも可
●RGBQUAD(カラーテーブル)
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
rgbBlue
青の輝度値
0~255
rgbGreen
緑の輝度値
0~255
rgbRed
赤の輝度値
0~255
rgbReserved
予約領域
常に0
biBitCountが1,4,8のとき、RGBQUAD構造体のカラーテーブルが指定されます。
biBitCountが24,32のときは存在しません。
ただし、biCompressionがBI_BITFIELDS かつ、biBitCountが16,32の場合、
多ビット(10Bit,12Bitなど)が表示可能となり、ビットフィールドが指定されます。
■画像データ
モノクロ画像の場合、輝度値が格納されています。
24Bitカラーの場合、B ,G ,R ,B ,G ,R ・・・ の順で各輝度値が格納されています。
32Bitカラーの場合、B ,G ,R ,A,B ,G ,R ,A・・・ の順で各輝度値が格納されています。
画像データは、画像の左から右、下から上へ向かう順番で格納されます。
また、1行あたりのメモリのサイズは4の倍数バイト になるように調整されています。
この値は以下のようにして計算しています。
VBの場合
((biWidth * biBitCount + 31) \ 32) * 4
Cの場合
((biWidth * biBitCount + 31) / 32) * 4
4の倍数バイト(32ビットの倍数)になるように調整しています。
ビットマップファイルを開く場合の注意点について
ビットマップファイルを開く場合、ヘッダ情報をもとに画像データ格納用のメモリを確保し、
そのメモリにデータを格納しますが、ヘッダの値はすべて正しく記載されているとは限りません。私の場合、以下の値を信じてメモリの確保などを行っています。
biWidth, biHeight, biBitCountを用いて画像データ格納用メモリの確保
biOffBits を用いて、画像データまでのファイルのシークを行う。
biSizeやbiSizeImage などは信じない方が良いと思います。