C言語で画像処理
C言語の基本的な文法に関してはC言語の連載に任せるとして、ポインタや配列、関数といったものを実際使用してちょっとしたプログラムを作成してみます。
今回はC言語での画像処理を行います。WindowsやLinuxには、画像処理用のソフトが既に付属していますが、今回はプログラムから切り取りや縮小、反転などの処理を行う予定です。画像データの形式としては「bmp」「jpg」などがあります。今回は扱いやすい「bmp」を使用することにします。
ビットマップファイルについて
BMP(ビットマップ)ファイルというのはデバイス独立ビットマップ(Device-Independent Bitmap)を画像として保存したものになります。DIBは色情報を持つことでデバイスに依存しないで利用できるという特徴があります。BMPはDIBにファイルの情報が付け加わったものとなっています。
ビットマップファイルの構造は以下のようになっています。
格納されているデータ | 説明 |
---|---|
BITMAPFILEHEADER | ビットマップファイルに関しての情報(サイズなど)が格納されています。 |
BITMAPINFOHEADER | ビットマップファイルに関しての詳細情報(縦幅、横幅)が格納されています |
カラーパレット | インデックスカラーを使用するときの色情報です。 |
画像データ | 実際のピクセルの色情報です。 |
このような4つの領域から構成されます。
「BITMAPFILEHEADER」「BITMAPINFOHEADER」内には様々な情報が格納されています。「カラーパレット」には、ピクセルの色情報が格納されています。画像データの部分には色データもしくはパレット番号が格納されています。
表示されている色の情報を変更する場合はこの画像データの部分の値を変更すればよいことになります。
BITMAPFILEHEADER
次にそれぞれの詳細な情報をみていきます。
まず「BITMAPFILEHEADER」には、以下の情報が格納されています。
変数名 | サイズ | 説明 |
---|---|---|
bfType | 2バイト | ファイルのタイプを表します。’BM’と格納されます。 |
bfSize | 4バイト | ファイルのサイズをバイト単位で表します。 |
bfReserved1 | 2バイト | 予約されている領域です。現状では常に0です。 |
bfReserved2 | 2バイト | 予約されている領域です。現状では常に0です。 |
bfOffBits | 4バイト | ファイルの先頭から画像データまでのオフセットです。 |
プログラミングの際、「bfType」を確認することで、BMPファイルかどうかの判定が可能です。
この構造体自体は14バイトですが、実際にプログラミングで構造体を使用する際には14バイト以上の大きさになることもあります。構造体のアライメントのためです。
BITMAPINFOHEADER
「BITMAPINFOHEADER」は、以下の情報が格納されています。
変数名 | サイズ | 説明 |
---|---|---|
biSize | 4バイト | 40バイトになります。 |
biWidth | 4バイト | 画像の幅となります。 |
biHeight | 4バイト | 画像の高さとなります。 |
biPlanes | 2バイト | プレーン数 1を指定します。 |
biBitCount | 2バイト | 1ピクセルあたりのデータサイズです。ビット数で指定します。1bit-2色 4bit-16色 24bit-1677万色 |
biCompression | 4バイト | 圧縮形式を指定します。0は無圧縮、1は4bitのランレングス圧縮 2は8bitのランレングス圧縮 3はビットフィールドになります。 |
biSizeImage | 4バイト | イメージのサイズを表します。 |
biXPixPerMeter | 4バイト | 1メートルあたりのピクセル数を表します。 |
biYPixPerMeter | 4バイト | 1メートルあたりのピクセル数を表します。 |
biClrUsed | 4バイト | 格納されているパレットの数を表します。 |
biClrImportant | 4バイト | 重要なパレットのインデックスを表します。 |
圧縮形式ですが、通常は無圧縮となります。圧縮される際は、ランレングス圧縮を使用します。
「biSizeImage」はイメージのサイズを表しています。ここでいうイメージとは画像データの入っている部分だけで「BITMAPFILEHEADER」や「BITMAPINFOHEADER」は含まれません。その下の4項目ですが0と成ることも多くなっています。
カラーパレット
カラーパレットは8ビットから以下の場合にのみ存在する項目です。カラーパレットは
Blue、Green、RedとReserveの4バイトで1つの色を表すよう構成されています。
画像データ
画像データには、各ピクセルの色情報が入ります。画像データは一般的に画像の左下から水平方向の順に格納されていき、24ビットカラーの場合BGRの順で色情報が保存されています。
画像データの先頭の8ビットの情報は実際に画面に表示されるビットマップの左下のピクセルの青色の度合いを表すことになります。次の8ビットは緑色の度合いその次は赤色の度合いとなります。次の8ビットは左下から右に1ピクセルずれた位置の青色の度合いとなります。ここで少し光の3原色についてみてみましょう。
光の3原色
Red、Green、Blueは光の3原色といわれています。この3色の割合によりディスプレイに表示される色を表しています。24ビットカラーの場合、1色だけで0~255の度合いがありその量で様々な色を表すことができます。例えばR255G255B255の場合、白色となりR0G0B0の場合、黒色となります。
また色には明度、彩度、色相3要素があります。
明度とは色の明るさの度合いであり、白色が最も高くなります。
彩度とは色の鮮やかさであり、赤色が最も高くなります。
色相とはRGBの色合いのことをいいます。
これらの情報が画像データに並んでいます。
画像データの配置ルール
画像データのビット配置にはあるルールがあります。横のラインの配置に関して1ラインに並ぶバイト数は4の倍数にしておかなければならないというものです。4の倍数にならなかった場合、0を4で割り切れる数になるまで埋めるようになっています。
画像の横幅が4の倍数になっている場合や32ビットカラーの場合は問題ありませんが、そうでない場合、処理する際に注意しなければなりません。
例えば画像のサイズが50×50だった場合、一般的な24ビットカラーのビットマップであれば1ラインに並ぶバイト数は3×50=150バイトとなります。
このとき実際は2バイト分0が補間されるため1ラインは152バイトとなります。
実際の色データ部分のサイズは152×50=7600となります。これを50×50×3で計算してしまうと画像処理を行った場合、ピクセルのずれが生じ崩れた画像となります。
こうしたことに気をつけて次回から実際のプログラムを作成していきましょう。