ビットマップファイルの構造 その1
Category:ComputerScience
Tags:FileFormat, ImageProcessing
仕事で画像処理をしております。
大学でも画像処理なんて勉強したこと無くて、会社でも勉強会とか研修とか全然無くて思いっきりOJT(On the Job Training:要は仕事するうちに覚えろということw)。
なのにいつの間にか画像処理をそれなりに使えるようになってきた。
入社当初はプログラミングもほとんどわからなかったのにw
一度画像処理の基礎から勉強しなおそうと思い立って、自分で一から画像処理ライブラリを作りながらここにまとめていきます。
ホントに独学なので間違って覚えていることは突っ込んでもらおうと(笑)
画像処理をするにあたって
まずは、画像処理をするにあたって、画像ファイルをメモリ上で処理できる形にしなければならないです。
画像処理では主にDIB(Device Independent Bitmap:デバイス独立ビットマップ)の画像データ形式を扱います。情報が非圧縮で1画素ずつ順番に入ってるので処理に便利。
WindowsのBMPファイルはDIB形式のファイル。WindowsでプログラミングしてるのでBMPしか扱ったことがありませんがまぁほとんど一緒でしょう(ぉぃ)
ということでDIB形式についてのまとめ。
DIBの構造
DIBのファイルはファイルヘッダ・画像情報・(カラーテーブル)・画像データで構成されます(カラーテーブルがカッコで書かれているのは後述)。ファイル構造は上図参照。
VC++とかだと、これ専用の構造体が用意されていて、この構造体のサイズ分をファイルから順番に読み込んでいけば正しく読み込める!というわけで便利です。
各構成要素の解説
ファイルヘッダ
BITMAPFILEHEADER構造体で表現される。
ファイルの基本情報が詰め込まれています。どんなファイルなのか等 etc...
BITMAOPFILEHEADER構造体の中身は、
typedef struct tagBITMAPFILEHEADER {
WORD bfType; // BMPファイルなら"BM"=0x4D42
DWORD bfSize; // ファイルサイズ(単位:Byte)
WORD bfReserved1;// 予約領域
WORD bfReserved2;// 予約領域
DWORD bfOffBits;
// ファイル先頭から画像データ先頭までのオフセット(Byte)
} BITMAPFILEHEADER;
- bfType
- ファイルタイプ
- WindowsのBMPなら必ず"BM"となる。そうじゃなければビットマップファイルでない。
- bfSize
- ファイルサイズ(Byte)
- このファイルのサイズを指定しておく。
- bfReserved1
- bfReserved2
- 予約領域
- 今現在使われてなく、0にすること。
- bfOffBits
- 画像データまでのオフセット(Byte)
- ビットマップファイルの先頭から画像データ領域までのオフセット数(Byte)。少し複雑なので詳しくは後述。
BITMAPFILEHEADER構造体の情報はファイルの基本情報なので画像を扱うには重要ではないですが、他のアプリケーションで扱う場合に(たとえばWindowsのペイントやWindows Picture and Fax Viewer、その他画像ビューワー、レタッチなどのための画像加工ソフトなど)このファイルヘッダの情報を扱っている場合があるのでなるべくきちんと処理するほうが良い。(と思われる(個人的見解
画像情報
BITMAPINFOHEADER構造体で表現される。
画像情報が詰め込まれています。画像サイズ、1ピクセルあたりのカラービット数、などなど。重要な情報です。
BITMAPINFOHEADER構造体の中身は、
typedef struct tagBITMAPINFOHEADER {
DWORD biSize; // この構造体(BITMAPINFOHEADER)のサイズ
DWORD biWidth; // 画像幅サイズ(px)
DWORD biHeight; // 画像高さサイズ(px)
WORD biPlanes; // プレーン数(???)
WORD biBitCount; // 1ピクセルあたりのカラービットの数
DWORD biCompression; // ビットマップの圧縮形式指定
DWORD biSizeImage; // 画像データの全バイト数
DWORD biXPelsPerMeter;// 水平方向解像度(px/mm)
DWORD biYPelsPerMeter;// 垂直方向解像度(px/mm)
DWORD biClrUsed; // カラーテーブルのエントリ数
DWORD biClrImportant; // 表示用カラーテーブルのエントリ数
}BITMAPINFOHEADER;
- biSize
- この構造体のサイズ
- BITMAOPINFOHEADERは40バイトなので常に40
- biWidth
- 画像横サイズ。説明省略
- biHeight
- 画像縦サイズ
- biHeightが正のとき、ビットマップ画像は左下原点。画像データ列が左下から上に並べられていることになる。負のときは左上原点。
- ちなみにビットマップ以外の多くの画像ファイルは左上原点の形式になっている。ディスプレイの画面も左上原点なのでビットマップを扱う場合はこの点に注意しなければならない。(何度苦しめられたことかw
- biPlanes
- プレーン数
- よくわからないまま1にしています(汗)
- biBitCount
- 1ピクセルあたりのカラービットの数
- 1,4,8,16,24,32 (bit) のみ使える。
- biCompression
- ビットマップの圧縮形式
- ランレングスとかJPEGとか。ここでは画像処理のため圧縮は使用しない。圧縮画像の話はまた機会があれば。
- biSizeImage
- 画像データの全バイト数
- biXPelsPerMeter
- biYPelsPerMeter
- 画像解像度(px/mm)
- それぞれX,Y方向の画像解像度を示す。0を指定しても良い
- biClrUsed
- カラーテーブルのエントリ数
- 実際にビットマップファイルに組み込まれているテーブルの数。0を指定するとbiBitCountで指定した分使用できる最大数を持っていることになる
- biClrImportant
- 表示用カラーテーブルのエントリ数
- ビットマップを表示するのに必要な(重要な)カラーテーブル数。0を指定すると全ての色が重要になる。
カラーテーブル
カラーテーブルはRGBQUAD構造体で表現します
RGBQUAD構造体1つで1つの色を示す。
RGBQUAD構造体の中身は、
typedef struct tagRGBQUAD {
BYTE rgbBlue; // 青チャンネルの輝度値(0~255)
BYTE rgbGreen; // 緑チャンネルの輝度値(0~255)
BYTE rgbRed; // 赤チャンネルの輝度値(0~255)
BYTE rgbReserved; // 予約領域(常に0にする)
} RGBQUAD;
っと、説明はいらないでしょう(笑)
画像データ
ピクセルのデータが1つずつ順番に格納されています。もちろん一番多く一番重要なデータw
こちらもあまり説明はいらないでしょう。ただ後で少し注意点を。
参考
こちらを見る方が詳しいかも。。ここではわかりやすくしたつもりですがw
その2へ
DIBの構造は以上ですが注意点がいくつかあるのでそれは「その2」でw