DATE : 2006/09/15 (Fri)
(前回の記事)
メソッドの抽出 (3)
前回に続いてさらに、「4 : 2の WritableRaster のアルファ成分を設定」の部分
WritableRaster alphaRaster = destRaster. createWritableChild(0, 0, width, height, 0, 0, new int[]{destRaster.getNumBands() - 1}); // 可視領域を表すアルファ成分のみの Raster WritableRaster visibleMaskRaster = createVisibleAlphaRaster(image); alphaRaster.setRect(visibleMaskRaster);
を setAlphaSamplesメソッドに抽出します。
/** * 指定の WritableRaster にアルファ成分を設定します。 * ただし、WritableRaster には、アルファ成分を格納するバンドが * 存在しなければなりません。 * * @param image アルファ成分を追加する元となる画像 * @param dest アルファ成分を追加する WritableRaster */ private static void setAlphaSamples( RenderedImage image, WritableRaster dest) { WritableRaster alphaRaster = dest. createWritableChild(0, 0, width, height, 0, 0, new int[]{destRaster.getNumBands() - 1}); // 可視領域を表すアルファ成分のみの Raster WritableRaster visibleMaskRaster = createVisibleAlphaRaster(image); alphaRaster.setRect(visibleMaskRaster); }
しかし、メソッドを抽出していてふと思いました。上のメソッドでは、アルファ成分のみの Raster を生成して、WritableRaster のアルファ成分として設定しています。ところが、ここで設定するアルファ値は全画素で共通のはずです。すると、わざわざアルファ成分のみの Raster を生成するよりも、直接アルファ成分を設定した方がコードは簡単になります。
そこで、上のコードを、直接アルファ成分を設定するように変更します。
/** * 指定の WritableRaster にアルファ成分を設定します。 * ただし、WritableRaster には、アルファ成分を格納するバンドが * 存在しなければなりません。 * * @param raster アルファ成分を設定する WritableRaster */ 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, 0xff); } } }
ここでは、最大のアルファ値として 0xff を設定しています。ところが、1バンクの幅が1バイトを超えると、0xff は最大のアルファ値とはなりません。例えば、WritableRaster(Raster)の転送型が java.awt.image.DataBuffer#TYPE_INT の場合は、符号付き4バイト値(int型)でアルファ値が表されることになります。そのため、0xff を int 型の最大値に変更します。(バンク幅を超えた値は、バンク幅に合わせてビットが切り捨てられます)
raster.setSample(x, y, alphaBand, Integer.MAX_VALUE);
また、Integer.MAX_VALUE に「アルファ値」としての意味を持たせるため、定数として抽出します。
結果、setAlphaSamples メソッドは次のようになります。
private static final int ALPHA_VALUE = Integer.MAX_VALUE;
/** * 指定の WritableRaster にアルファ成分を設定します。 * ただし、WritableRaster には、アルファ成分を格納するバンドが * 存在しなければなりません。 * * @param raster アルファ成分を設定する WritableRaster */ 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); } } }
初めに抽出したメソッドと比べて、引数が1つ減りました。
また、createVisibleAlphaRaster メソッドを使う必要がなくなりました。そのため、このメソッドは消去しておきます。
なお、「4 : 2の WritableRaster のアルファ成分を設定」の部分は次のように変わります。
setAlphaSamples(destRaster);
最後に、「5 : BufferedImage の生成」の部分です。
return new BufferedImage(destColorModel, destRaster, false, null);
しかし、この部分はコメントの通り BufferedImage を生成しているだけなので、メソッドには抽出しません。
ただ、アルファの乗算状態を false と決め打ちにしているところは気になります。そこでこの部分を、処理対象の画像のカラーモデルと同じ状態になるように変更します。
return new BufferedImage(destColorModel, destRaster, destColorModel.isAlphaPremultiplied(), null);
(つづきます)