IndexColorModel
gifイメージの出力の続きです
じゃあIndexColorModelとはなんなのか。
先回参照したhttp://wisdom.sakura.ne.jp/system/java/awt/Gjava40.html
にわかりやすく記載されているのですが、ずっとどうもピンと来なかった。
bitsには1ピクセル当たりのビット数を
sizeには色成分の配列のサイズ(要素数)を指定しますr[]には赤成分の配列、g[]には緑成分の配列、b[]には青成分の配列を指定します
たとえば r[0] = 255 , g[0] = 0 , b[0] = 0 で、インデックス0番が赤になります
ってこれがそのままズバリだったのですが、ピクセル?赤緑青の配列?
とか色々考えてしまいハマりました。
ソースコードを引用させていただきます。
import java.applet.Applet; import java.awt.*; import java.awt.image.*; /* */ public class test extends Applet { Image img; MemoryImageSource mi; public void init() { byte a[] = { (byte)100 , (byte)255 , (byte)20 }; byte r[] = { (byte)255 , (byte)0 , (byte)0 }; byte g[] = { (byte)0 , (byte)255 , (byte)0 }; byte b[] = { (byte)0 , (byte)0 , (byte)255 }; IndexColorModel icm = new IndexColorModel(8 , 3 , r , g , b , a); int ary[] = { 0 , 0 , 0 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 0 , 0 , 0 , 1 , 1 , 1 }; mi = new MemoryImageSource(9 , 2 , icm ,ary , 0 , 9); img = createImage(mi); } public void paint(Graphics g) { g.drawImage(img , 0 , 0 , 300 , 300 , this); } }
で、言えば、以下のようなパレットが作成されることになります。
パレット番号0 → alpha 100, red 255, green 0, blue 0 = 0×64ff0000
パレット番号1 → alpha 255, red 0, green 255, blue 0 = 0xff00ff00
パレット番号2 → alpha 20, red 0, green 0, blue 255 = 0×140000ff
alpha, red, green, blueのバイト配列を作成し、その添字が番号となるわけです。
上記は3パターンですが、これを増やせば扱う色のバリエーションも増えるわけです。
GIFであれば、Webセーフカラーの216色の
パレットを作れば良いかな?
配列の上限数が[Java][Tips] Javaの配列の大きさは、いくつまで指定できるかによれば
よって「Javaの配列の次元数あたりの長さに指定できる最大値は、int型の正の値の最大値である」ということになりそうです。
だそうなので、約21億通りの色が保持出来るのだろうか。やらないけど。ヒープが足りなくなりそうだから。
そして透過色はどのようにするか?
IndexColorModelのソースコードを見ると(長いのでsetRGBsの一部だけ)
int alpha = 0xff; int transparency = OPAQUE; boolean allgray = true; for (int i = 0; i < size; i++) { int rc = r[i] & 0xff; int gc = g[i] & 0xff; int bc = b[i] & 0xff; allgray = allgray && (rc == gc) && (gc == bc); if (a != null) { alpha = a[i] & 0xff; if (alpha != 0xff) { if (alpha == 0x00) { if (transparency == OPAQUE) { transparency = BITMASK; } if (transparent_index < 0) { transparent_index = i; } } else { transparency = TRANSLUCENT; } allgray = false; } } rgb[i] = (alpha << 24) | (rc << 16) | (gc << 8) | bc; }
どうも、アルファ値が0xffでなくて、0xffの場合にOPAQUE
(完全に不透明であることが保証される)
ならばBITMASK
(完全に不透明 (アルファ値が 1.0) である、あるいは完全に透明)に変更されるようです。
0xffと0×00以外ならTRANSLUCENT
(任意のアルファ値)
になるようです。gifの場合は透過色をひとつしか指定出来ないということで、BITMASKが指定されれば良い。
ということは、アルファ値を0×00にすれば良さそうですね。
次回は実際にやってみます。
それにしても画像表示系の処理は論理演算やシフト演算が多いです。