| 画像 | 色数 | 大きさ |
|---|---|---|
| 2色 | 1bit | |
| 8色 | 3bit | |
| 256色 | 8bit | |
| 16色 | 4bit | |
| 256色 | 8bit | |
| 1677万色 | 24bit |
コンピュータでは ピクセル (pixel) もしくは ドット (dot) と呼ばれる非常に小さな点でグラフィックを表示しています。グラフィック上の各ピクセルは独立した色を持つ事ができますが、一つのピクセルで使う事のできる色の数には制限があります。
ピクセルに対する色は固定された大きさの整数値で表されます。例えば 1 ピクセルあたり 4 ビットを使用するグラフィックは最大 16 色を使う事ができます。当然ながらピクセルの大きさが小さくなればきれいなグラフィックを表示できなくなってゆきます。
Sample Picture
人間が見て自然だと感じる色数はどの程度でしょうか? 通常コンピュータ上でグラフィックを扱う場合 1677 万色を使用できれば十分と言われています。24 ビットあれば 1677 万までの数値を扱う事ができるため、1 ピクセルあたり 24 ビット以上の大きさを持つグラフィックは フルカラー (Full Color) と呼ばれています。
幅 100 ピクセル、高さ 100 ピクセルの画像について考えてみましょう。この画像に含まれる全ピクセル数は 100x100=10,000 個になります。もし 1 ピクセルにつき 4 ビットの大きさを持つなら、この画像の大きさは 5,000 バイトとなります。つまり画像の大きさは以下のように計算する事ができます。
フルカラーが一つの色に 3 バイト使用し、3 つの基本色からなっているということは、一つの基本色につき 1 バイト使用していることになります。つまり基本色一つ当たり 256 階調あればフルカラー画像となります。モノクロ画像ではこれらの基本色の階調だけで表現するため、一つの色で 256 階調あれば自然な感じになります。
画像ファイルやコンピュータグラフィックなどでは、色を表現するために使用される基本色をチャンネルやプレーンと呼びます。
余談ですが、コンピュータの画面の色数と VRAM の大きさの話をします。フルカラーは一つの点につき 3バイトを使用します。では、フルカラーで 1280×1024 の大きさの画面を使用するにはどれくらいの VRAM が必要でしょうか?答えは 3×1280×1024=3,932,160 バイトです。つまり 4MB の VRAM が必要になります。では 256色ならどうでしょうか。256色は一つの点につき 1バイト使用します。したがって 1,310,720バイト、つまり 2MB の VRAM が必要になります。このようにして画面の色数と解像度、VRAM の大きさの相関関係を知ることができます。
コンピュータで使用されるモニタ上では、一つの色につき赤、緑、青の三色を使用して表現しています。このような方法は RGB カラーモデルと呼ばれ、それぞれの色を重ねあわせて一つの色を表現します。テレビのブラウン管を見てください。よく見ると RGB の三色をそれぞれ一つの小さな点として表示し、離れてみるとそれらの点が交じり合って一つの色を表現しています。つまりカラーモデルとはその色をどのように表現するかという意味になります。
以下のアプレットはこのページで紹介している RGB カラーモデル、CMYK カラーモデル、HSB カラーモデルを体験するデモンストレーションです。同じ色でもそれぞれのカラーモデルで表現方法が違っています。スライダを移動させて色の変化の具合を確かめてみてください。アプレットのソースコードはこちらです。
| Color Model |
|---|
Java でカラーモデルが使用されるのはピクセルの配列を画像オブジェクトに変換するときです。配列が直接ピクセルの色を表している場合は DirectColorModel が使用され、カラーテーブルのインデックスを表している場合には IndexColorModel が使用されます。もちろん独自のカラーモデルを持つピクセル配列に対してプログラマがそれに対応する ColorModel サブクラスからカラーモデルを指定する事ができます。
コンピュータグラフィックで使用されるもっとも一般的なカラーモデルは RGB カラーモデルでしょう。RGB カラーモデルでは 赤、緑、青の基本色の強度によって一つの色を表します。このカラーモデルはモニタやテレビのブラウン管などで色を表現するために使用されています。
RGB カラーモデルでは基本色どうしを混ぜ合わせることで、より明るい色を表現することができます。つまり、それぞれの基本色の強さを混ぜ合わせることで色を表現しています。テレビを消してみてください。ブラウン管は黒くなりますね。テレビをつけるとブラウン管上の点に RGB それぞれの光が混ぜ合わされて色を作り出します。したがって RGB カラーモデルで一つの色を表すには以下のような関係が成り立ちます。
一つの基本色の強度は 0~255 までの階調を持ち、基本色すべてが 255 の場合に白色になります。RGB カラーモデルを使用したグラフィックでは、各ピクセルについて RGB の強度を保存していることになります。
| RGB | CMYK |
|---|---|
![]() | ![]() |
コンピュータで画像を制作したりグラフィックを制作する場合には RGB カラーモデルを使用するのが一般的ですが、最終的にプリンタなどで紙面上に出力することが想定されたグラフィックでは CMYK カラーモデルが使用されます。CMYK カラーモデルでは RGB カラーモデルと同様にシアン、マゼンダ、イエローの強度によって一つの色を表します。
CMYK カラーモデルは印刷に使用するインクを基準にして画像を扱っています。しかしインクの色再現性は画面上よりもかなり落ちます (色域が狭いと言う)。右の写真は同じ画像を RGB カラーモデルと CMYK カラーモデルで表しています (256 色画面では同じに見えるかもしれません)。鮮やかな色になるほど CMYK カラーモデルで表現性が落ちているのが分かります。
CMYK カラーモデルはコンピュータの画面上で使用される画像には使われませんが、最終的に印刷を目的とした画像処理作業を行う場合には、画面上の色と印刷の色とを厳密に合わせる必要があります。従って印刷で再現できない色を画面上でも再現できない CMYK カラーモデルが必要になってきます。
RGB カラーモデルと CMYK カラーモデルは簡単な相関関係にあります。どちらも基本色の表現に 256 階調 (8ビット) を使用する場合、RGB カラーモデルと CMYK カラーモデルの色は以下のように変換する事ができます。
| Cyan | = | 255 - Red |
|---|---|---|
| Magenta | = | 255 - Green |
| Yellow | = | 255 - Blue |
| C M Y K |
![]() |
|---|---|
| C M Y |
![]() |
論理的には CMY の基本色の混ぜ合わせで黒を作り出すことができるのですが、実際にそれらのインクを混ぜ合わせても黒にはならず、暗い灰色になってしまいコントラストがぼやけます。右の写真を見比べてみてください。黒を使用していない画像はなんだかちょっとぼやけていますね。低解像度の画面ではこの程度で済みますが、高解像度印刷ではもっと顕著な効果が現れます。
このような理由で、現在使用されている一般的なカラープリンタでは CMY のインクに加えて黒 K のインクを使用します。CMYK の K は Blue の B と混同しないように blacK の K (Key color の K という説もある) という意味です。
黒が使用される場合の RGB-CMYK の色変換はもっと複雑です。厳密には印刷に使用するインクの製品によって変換方法が違ってきますし、さらに同じインクでも印刷するときの機械の具合や温度、湿度などが絡んでくるので、実際問題グラフィックを制作するときに正しい変換と言うのはできません。
コンピュータグラフィックでは RGB カラーモデルや CMYK カラーモデルのほか、色調を色相 (Hue)、彩度 (Saturation)、明度 (Brightness) で表す HSB カラーモデルがあります。コンピュータ上でグラフィックの色を操作するには RGB や CMYK を使用するより HSB カラーモデルで指定したほうが直感的という利点があります。
HSB カラーモデルでの彩度は色の鮮やかさをあらわします。この値が低いとパステル調の落ち着いた色になります。明度は明るさを表しています。明度が大きくなると明るい色になり、小さいと暗い色になります。色相はまさに色を表しています。ちなみに明度のチャンネルだけを取り出した画像は、その画像のグレースケール版となります。
Java では HSB カラーモデルと RGB カラーモデルでの色の変換を行うためのメソッドが標準で用意されています。これは Color クラスの静的メソッド HSBtoRGB(), RGBtoHSB(), getHSBColor() です。これらのメソッドを使用すれば HSB カラーモデルを簡単に使用することができます。変換アルゴリズムについてはここで説明するよりも Java のソースコードを見てもらったほうが早いでしょう。
フルカラーを使用すればすべての色を表現することができますが、一つの色あたりに 24ビットを必要とするため、扱うデータが大きくなってしまいます。画像ファイルには 16 色しか使用していないものもあります。インデックスカラーモデルはグラフィックに色数の制限を設けて、効率を高めるためのカラーモデルです。フルカラー以外のほとんどの画像ファイルや Windows スクリーンなどがインデックスカラーモデルを使用しています。
インデックスカラーモデルはあらかじめ決まった数の色をカラーテーブル (パレット) として保存しておき、そのテーブルのインデックスによって点の色を表現するという方法を取っています。したがって、インデックスカラーモデルを使用した画像ファイルでの画像データとは、一つの点にあらかじめ用意されたカラーテーブルのインデックスが保存されることになります。
例えば 4 個のカラーテーブルエントリを持つ画像の大きさについて考えてみましょう。 カラーテーブルには 24 ビットの RGB 色が 4 個 (計 12 バイト) あります。画像の各ピクセルは 0~3 までの値を保存できれば十分ですから、1 ピクセルあたりの大きさは 2 ビットとなります。画像が 100x100 ピクセルの大きさの場合、全画像で使用されているピクセルの数は 10,000 個です。従って画像全体の大きさは 2,500 + 12 = 2,512 バイトとなります。
RGB カラーモデルを使用した 100x100 の画像について考えてみましょう。RGB カラーモデルでは各ピクセルに対して 24 ビット必要になりますから、画像全体の大きさは 10 倍以上の 30,000 バイトになってしまいます。色数制限のある画像ならインデックスカラーモデルを使用したほうがはるかに効率がよいと言えます。
インデックスカラーモデルのもう一つの利点に色の置き換えが容易であると言う事があります。インデックスカラーモデルはカラーテーブルで全ての色を管理していますから、このエントリの値を変更するだけで画像すべての色を変更する事ができます。これはネガ反転などの色に対する処理を行う場合に非常に有利です。
ダイレクトカラーモデルは Java で使用されているカラーモデルです。Java ではアルファカラー付き RGB カラーモデルを使用して一つの色を表していますが、ダイレクトカラーモデルは一つのピクセルの値がそのまま色の値に相当する事を表しています。
Java では一つの色を 32 ビット値で表しています。それぞれ 8 ビットごとにアルファカラーと基本色が設定されています。
厳密には RGB カラーモデルと Java におけるダイレクトカラーモデルとの定義が異なる事に注意してください。RGB カラーモデルは RGB 各色の情報のみを持ちアルファカラーを考慮していませんが、Java のダイレクトカラーモデルではアルファカラーを持っています。
さて、フルカラーでは 3バイトを使用してすべての色を表現することができますが、コンピュータが得意とする大きさは 4バイトです。そこで、あまった 1バイトはしばしばアルファカラー (Alpha Color) として使用します。アルファカラーとは『不透明度』に使用されたり『画像マスク』に使用されたりします。アルファカラーとは、ある色に対するおまけの情報みたいなものです。
たとえばアルファカラーを『不透明度』に使用した場合、不透明度が 0 の色は完全に透明になりますし、128 の場合には半分だけ背景に溶け込んだ色になります。255 なら完全に不透明になります。一般的にアルファカラーはこの不透明度に使用されています。
アルファカラーが使用されるのは不透明度だけではありません。たとえば画像にぼかしをかけるフィルタがあったとします。このフィルタが画像のアルファカラーを認識してぼかしの具合を決定する場合、画像のある部分だけを強くぼかしたりすることもできます。アルファカラーとは広い意味でのマスクといえます。
Java でも低レベルな画像処理では 0~255 階調のアルファカラーを扱う事ができます。ただし、今の所サポートされているのは完全な不透明 (α=255) と完全な透明 (α=0) だけです。これ以外の中間的なアルファカラーはすべて透明とみなされるでしょう。将来的には何らかのサポートが行われるかもしれませんし、サードベンダからアルファカラーに対応した製品が出るかもしれません。