DATE : 2006/08/22 (Tue)
java.awt.image.BufferedImage のあるコンストラクタが少々わかりづらいのでメモしておきます。
BufferedImage には、BufferedImage(java.awt.image.ColorModel, java.awt.image.WritableRaster, boolean, java.util.Hashtable) というコンストラクタがあります。
初めの ColorModel や WritableRaster は画像内のデータの解釈方法(ColorModel)と画像のデータ(Raster)であることは分かります。しかし、その後の boolean と Hashtable が謎です。
ちなみに、日本語版 API ドキュメントには、次のように書かれています。
public BufferedImage(ColorModel cm, WritableRaster raster, boolean isRasterPremultiplied, Hashtable,?> properties)
ColorModel および Raster を指定して、新しい BufferedImage を構築します。Raster の SampleModel のバンドの数および型が、色成分およびアルファ成分を表すために ColorModel によって要求される数および型と一致しない場合は、 RasterFormatException がスローされます。このメソッドは、ColorModel の alphaPremultiplied 状態と一致させるために色 Raster データをアルファで乗算または除算できます。この BufferedImage のプロパティは、String と Object のペアの Hashtable を渡すことによって確立できます。
- パラメータ:
- cm - 新しいイメージの ColorModel
- raster - イメージデータの Raster
- isRasterPremultiplied - true の場合、ラスタのデータはアルファによってあらかじめ乗算されている
- properties - String と Object のペアの Hashtable
この引用によると、boolean は『true の場合、ラスタのデータはアルファによってあらかじめ乗算されている』ことを、Hashtable は『BufferedImage のプロパティ』を表すようです。
Hashtable については、ドキュメントを調べるうちに解決できました。BufferedImage のスーパークラスである java.awt.Image を見る(Image#getProperty(String, java.awt.image.ImageObserver))と、次のように書かれていました。
プロパティ名「comment」を使用すると、イメージ、そのソース、またはその作成者の記述としてアプリケーションに提示できるオプションのコメントを格納できます。
どうも、画像に対する付加情報が Hashtable で設定できるようです。例えば、javax.swing.ImageIcon では、「comment」と設定したプロパティをアイコンの説明に使用するようです。(ImageIcon(java.awt.Image)
しかし、この付加情報はあくまでも「画像オブジェクト」に対するものであり、「画像ファイル」の付加情報ではありません。「画像ファイル」に対して、作者やコメントなどの付加情報を付ける場合は、ImageIO であれば javax.imageio.metadata.IIOMetadata を使わなければなりません。
次に boolean です。正直なところ、ドキュメントからはいまひとつ意味がつかめません。『ColorModel の alphaPremultiplied 状態と一致させるために色 Raster データをアルファで乗算または除算できます』という部分から、ColorModel#isAlphaPremultiplied() との関係がうかがえます。しかし、『Raster の SampleModel のバンドの数および型が、色成分およびアルファ成分を表すために ColorModel によって要求される数および型と一致しない場合は、RasterFormatException がスローされます。』という部分には、Raster と ColorModel とが対応しない場合は例外が発生すると書かれているので、alphaPremultiplied 状態が合っていないと例外が発生するようにも受け取れます。しかし、ColorModel#isAlphaPremultiplied() から alphaPremultiplied 状態は取得できるので、あえて引数として alphaPremultiplied を受け取る理由が分かりません。
そこで、BufferedImage(ColorModel, WritableRaster, boolean, Hashtable) のソースコードを調べてみました。すると、次の1行が見つかりました。
coerceData(isRasterPremultiplied);
上のコードは、次のメソッドを呼び出しています。(BufferedImage#coerceData(boolean))。
public void coerceData (boolean isAlphaPremultiplied) { if (colorModel.hasAlpha() && colorModel.isAlphaPremultiplied() != isAlphaPremultiplied) { // Make the color model do the conversion colorModel = colorModel.coerceData ( raster, isAlphaPremultiplied); } }
コンストラクタで指定された ColorModel (フィールドの colorModel)のalphaPremultiplied 状態と isAlphaPremultiplied とを比較して、異なる場合は引数に指定されたものと同じ状態の ColorModel を生成しています。また、ラスタのデータの計算も行っています。
ここから、BufferedImage(ColorModel, WritableRaster, boolean, Hashtable) の boolean は、BufferedImage の ColorModel の alphaPremultiplied 状態を設定する引数と言えます。