画像データの基本的な構造

ここではコンピュータ上で扱われる画像データの基本的な構造について解説します。 簡単な内容から高度な内容までを網羅しています。内容が進むにつれてより高度な内容を扱います。 もしも画像を扱うプログラミングなどをする必要がある場合には、内容を最後まで理解できる必要があるでしょう。

画像を構成する単位「画素」とは

画像は画素の集合である

画像は沢山の画素(ピクセル:pixel)の集合です。画素とは、画像を構成する情報の単位です。 画像を拡大すると見ることができる、1つの色で塗られた非常に小さな正方形をイメージすると良いと思います。

良く見かける「xx 万画素」とは、その画像がいくつの画素から構成されているかを表している、ということです。 例えばフルHDの画像とは 幅 1920px * 高さ1080px の画像のことですが、 これは 1920px * 1080px = 2,073,600 (≒200万) の画素から構成される画像ということになります。

同じような用語に"解像度"がありますが、解像度は画素数とは異なります。 解像度はある大きさの表示面に対して、どれだけの画素が含まれているかを示す単位です。 ただどちらの用語もほとんど変わらない意味で利用されているケースが多いです。

画素を構成する要素

画像は画素に分解することができますが、画素もさらに細かな情報に分解することができます。 画素は1つの色で塗られた正方形ですから、さらに細かな情報とは、その色を表す情報のことです。

色(画素)を表現する方法(= フォーマット)はいくつか種類がありますが、 一般的には BGR や BGRA、または RGB や RGBA という単位に分解され、表現されます。 ここでは BGRA を例に解説を進めます。

画素は4つの色情報 RGBA から構成される

BGRA とは、ある色をそれぞれ、B(青)・G(緑)・R(赤)・A(透明度) という4つの成分から表すことを示します。 青と緑を足したら黄色になる、といった色の作り方を覚えているでしょうか。緑が多ければ黄緑になりますね。 基本的に色は B・G・R の 3 色の量の加減と、その明暗(白っぽい、黒っぽい)によって表現することができます。 そして画像データでは RGB がすべて最大値のとき混ざり合ってできる色は白になります。絵具はほぼ黒ですけどね。 このような色の混ざり方を加法混色といいます。(A は透明度です。色には直接の関係がありません。)

一般に、それら BGRA の値はそれぞれ 8bit(= 1byte) で表されます。 つまり 1 つの画素は 8 * 4 = 32bit = 4byte で表されるということです。

bit とは 2進数の 1 桁分の単位です。8bit は 2進数が 8 桁分であることを示します。 8bit で表現できる数値は、10 進数では 0~255 となります。 つまり BGRA の値はそれぞれ 0~255 の値で表されるということになります。

32bit の画像とは RGBA がそれぞれ 8bit の数値で表現されていることを指します。 24bit の場合には A(透明度) の値が含まれていない画像になります。(ただし用途によって例外は多くあります)

BGR を採用している画像フォーマットは .bitmap などです。 また BGRA を採用している画像フォーマットは .png などです。

画像のデータサイズ(情報量)

高さ 512px 幅 512px の画像があるとき、画素数は 512px * 512px = 262,144px です。 この画像のフォーマットが BGRA 32bit であるとき、1 画素あたりの情報量は 32bit = 4byte ですから、 262,144px * 4byte = 1,048,576 byte でおよそ 1Mbyte (メガ) になります。

ただしこの算出方法は情報を圧縮していない場合に限ります。 多くの場合に画像データは圧縮されていますね。

画像の座標系

一般に、ある画素(ピクセル)の座標(位置)は、その画像の左上を原点 (0, 0) とする二次元の座標系で表されます。

画素を表すための座標系

画像を配列で表現する

画像は画素で構成され、画素は BGRA の4つの成分で構成されることが分かりました。 つまり画像は沢山の BGRA によって構成されている、ということになります。

基本的に、コンピュータ上では画像は BGRA の一次元配列によって管理されます。 したがって画像を扱うプログラミングではこの一次元配列を扱うことになります。 多くの場合には byte の配列でしょう。

画像は配列で構成されている

ストライド

画像データには「ストライド(stride)」という重要な概念があります。

画像は二次元の絵として画面上に表現されますが、内部的には一次元配列として管理されています。 配列には高さや幅の情報は与えられていませんから、 コンピュータが一次元の配列を二次元の絵にするためには、 配列の何番目から何番目までのデータが画像の横一列分に相当するのかを表す値が必要になります。 その値がストライド(stride)です。一般的には byte で表現されます。

例えば、幅が 512px でフォーマットが BGRA 32bit の画像があるとします。 この時のストライドは 512px * 4byte(= 32bit) = 2048byte になります。

ストライドの概念

ある画素 (x,y) のデータを参照する

ストライドが得られると、ある画素 (x, y) のデータが、配列のどの位置に (index) に保存されているかを求められます。 例えば 幅 512px * 高さ 512px の BGRA 32bit 画像中にある、画素 (120, 247) を参照するときは、次のようにします。

ストライドは 512px * 4byte = 2048byte です。したがって (120, 247) の index は 4byte * 120px + 247px * 2048 = 480 + 505856 = 506336 となります。 配列の「506336 ~ 506336 + 3」番目に、画素 (120,247) の BGRA 成分が保存されていることが求められました。