DATE : 2006/09/01 (Fri)
(前回の記事)
3. BufferedImage 用の WritableRaster の色成分(アルファチャンネルを除いた成分)部分に、RenderedImage の画素値をコピーする
setColorSamples(destRaster, image.getData());
ここでは、対象の画像の Raster と、BufferedImage 用の WritableRaster を使って setColorSamples メソッドを呼び出しています。
setColorSamples の内容は、次の通りです。
private static void setColorSamples(WritableRaster dest, Raster src) { WritableRaster colorRaster = dest.createWritableChild( 0, 0, dest.getWidth(), dest.getHeight(), 0, 0, getBandListExceptAlpha(dest)); colorRaster.setRect(src); }
まず、 java.awt.image.WritableRaster#createWritableChild(int, int, int, int, int, int, int[]) を使って、色成分のみを表す WritableRaster を取り出します。このメソッドの最後の引数は、取り出すバンドの番号を並べた配列です。例えば、0, 1, 2 番のバンドを取り出す場合は、0, 1, 2 と格納された int 型の配列となります。ここでは、1つのバンドが色成分ひとつに相当すると考えても良いと思います。
なお、アルファ値は、最後のバンドがアルファ値のバンドになります(java.awt.image.ColorModel#getAlphaRaster(java.awt.image.WritableRaster) 参照。実際に、java.awt.image.ComponentColorModel のソースコードを調べると、確かに最後のバンドがアルファ値のバンドとして扱われていました)。
そこで、 getBandListExceptAlpha メソッドを使用して、アルファ値以外のバンド番号を取得します。このメソッドの内容は、次のようになります。
private static int[] getBandListExceptAlpha(Raster raster) { int[] bandList = new int[raster.getNumBands() - 1]; for (int i = 0; i < bandList.length; i++) { bandList[i] = i; } return bandList; }
ただ単に、全バンドから最後のバンド番号を除いた配列番号を生成しているだけです。
ただし、このメソッドは、アルファ値を持たない Raster を渡すとおかしな結果を返すことになります。今回は必ずアルファ値のバンドを持っているので、このような簡単な形になっています。
4. BufferedImage 用の WritableRaster にアルファチャンネル部分の値を設定する
setAlphaSamples(destRaster);
BufferedImage 用の WritableRaster を使って setAlphaSamples メソッドを呼び出しています。このメソッドの内容は、次の通りです。
private static final int ALPHA_VALUE = Integer.MAX_VALUE; private static void setAlphaSamples(WritableRaster raster) { int alphaBand = raster.getNumBands() - 1; for (int y = 0; y < raster.getHeight(); y++) { for (int x = 0; x < raster.getWidth(); x++) { raster.setSample(x, y, alphaBand, ALPHA_VALUE); } } }
引数の WritableRaster のアルファ値を表すバンドに、int 型の最大値を設定しています。この int 型の最大値は、アルファ値の最大値を表します。つまり、このメソッドでは、完全に不透明を表す値を設定していることになります。
なお、このメソッドもアルファチャンネルを持たない WritableRaster を渡すとおかしな結果になります。
5. BufferedImage 用の WritableRaster にアルファチャンネル部分の値を設定する
return new BufferedImage(destColorModel, destRaster, destColorModel.isAlphaPremultiplied(), null);
これまでの手順で BufferedImage 用の ColorModel や WritableRaster ができたので、これらを使った java.awt.image.BufferedImage のコンストラクタで BufferedImage を生成します。アルファの乗算状態は特にこだわらないので、ColorModel と同じ状態に設定しています。
以上で、アルファチャンネルを持った BufferedImage を生成することができました。
(了)