忍者ブログ
[4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14]

DATE : 2024/03/19 (Tue)
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。


DATE : 2006/08/30 (Wed)

前回の記事

BufferedImage にアルファチャンネルを追加するコード(一部)は、次のようになります。(import 文などは省略してあります)。

ここで、image はアルファチャンネルを追加する対象の画像(RenderedImage)、最後の return 文で返されるオブジェクトが、アルファチャンネルが追加された画像(BufferedImage)です。

// 1
ColorModel destColorModel =
	createColorModelWithAlpha(image.getColorModel());
// 2
WritableRaster destRaster = destColorModel.
	createCompatibleWritableRaster(
		image.getWidth(), image.getHeight());

// 3		
setColorSamples(destRaster, image.getData());
// 4
setAlphaSamples(destRaster);

// 5	
return new BufferedImage(destColorModel, destRaster,
	destColorModel.isAlphaPremultiplied(), null);

コメントで示したとおり、上のコードは5つの手順に分かれています。ここからは、それぞれの手順を細かく見ていくことにします。

1. BufferedImage 用に、アルファチャンネル付きの java.awt.image.ColorModel を生成する

ColorModel destColorModel =
	createColorModelWithAlpha(image.getColorModel());

ここでは、createColorModelWithAlpha メソッドに、対象となる画像のカラーモデルを渡すことでアルファチャンネル付きのカラーモデルを生成しています。

createColorModelWithAlpha メソッドは、次のようなメソッドです。

private static ColorModel createColorModelWithAlpha(ColorModel src) {
	return new ComponentColorModel(src.getColorSpace(), true,
		src.isAlphaPremultiplied(), Transparency.BITMASK,
		src.getTransferType());
}

渡されたカラーモデルと同じ色空間、アルファ値の乗算状態、サンプルの型で、それでいてアルファ値をもつようなカラーモデルを生成しています。

なお、「Transparency.BITMASK」は、透明部分が「完全に不透明、もしくは完全に透明」であることを表します。つまり、アルファ値が1(不透明)か0(透明)かに限定されるわけです。もしも、任意の透明度を設定したい場合は、「Transparency.TRANSLUCENT」にします。(Transparency インタフェースは、java.awt パッケージにあります)

2. BufferedImage 用に、上の ColorModel が扱える java.awt.image.WritableRaster を生成する

WritableRaster destRaster = destColorModel.
	createCompatibleWritableRaster(
		image.getWidth(), image.getHeight());

java.awt.image.ColorModel には、そのカラーモデルが扱える WritableRaster を生成するメソッドがあります。

そのため、ここではそのメソッドを利用することで、生成したカラーモデルが扱える WritableRaster を生成しています。

つづきます

PR

DATE : 2006/08/23 (Wed)

java.awt.image.BufferedImage などの java.awt.image.RenderedImage にアルファチャンネルを追加した BufferedImage を作るには、次のような手順で処理を行います。

以下の手順では、「RenderedImage」がアルファチャンネルを追加する対象の画像オブジェクト、「BufferedImage」がアルファチャンネルを追加した画像オブジェクトとします。

  1. BufferedImage 用に、アルファチャンネル付きの java.awt.image.ColorModel を生成する。
  2. BufferedImage 用に、上の ColorModel が扱える java.awt.image.WritableRaster を生成する。
  3. BufferedImage 用の WritableRaster の色成分(アルファチャンネルを除いた成分)部分に、RenderedImage の画素値をコピーする。
  4. BufferedImage 用の WritableRaster にアルファチャンネル部分の値を設定する。
  5. BufferedImage 用に生成した ColorModel と WritableRaster から、BufferedImage を生成する。

サンプルコードは少々長いので、次の記事に掲載しようと思います。

つづきます


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 状態を設定する引数と言えます。

参考文献


DATE : 2006/08/21 (Mon)

java.awt.image.RenderedImage から java.awt.image.BufferedImage を生成するには、次のような手順で行います。

  1. RenderedImage からカラーモデル(java.awt.image.ColorModel)とラスター(java.awt.image.Raster)を取得する。
  2. ラスターは読み取り専用なので、書き換え可能なラスター(java.awt.image.WritableRaster )を取得する。
  3. WritableRaster と ColorModel から、BufferedImage を生成する。

コードにすると、次のようになります。ここで、source は BufferedImage を生成するための RenderedImage です。(import 文などは省略してあります)

ColorModel colorModel = source.getColorModel();
WritableRaster raster = source.getData().
    createCompatibleWritableRaster();

BufferedImage image = new BufferedImage(colorModel, raster,
    colorModel.isAlphaPremultiplied(), null);

コードに示したとおり、BufferedImage には、WritableRaster や ColorModel からインスタンスを生成できるコンストラクタがあります。

その最後から2番目の引数は、アルファ値を Raster のデータにあらかじめ乗算しておくかどうかを指定します。ここでは特にこだわらないため、ColorModel の設定どおりにしました。

また最後の引数は java.util.Hashtable で、画像のプロパティを設定できます。ただし、今回はプロパティがないので null にしました。(BufferedImage のソースコードを見たところ、null に対応するコードがあったので、特に問題はないと思います)

参考文献


DATE : 2006/08/19 (Sat)

分割画像の作りかた」や「分割画像の作りかた 2」で生成した分割画像片を BufferedImage に取り出すには、次のようなコードを記述します。

なお、tileX は分割画像の水平方向での番号、tileY は垂直方向での番号です。また、対象の分割画像を格納する source は javax.media.jai.PlanarImage です(RenderedOp や TiledImage も PlanarImage です)。(import 文などは省略してあります)

Rectangle tileRect = source.getTileRect(tileX, tileY);

BufferedImage tile = source.getAsBufferedImage(tileRect,
    source.getColorModel());

getTileRect メソッドで画像片の領域を取得し、その領域内の内容を BufferedImage として取得します。

簡単なコードですが、API ドキュメントの中に埋もれていたので取り上げてみました。

((´・ω・)実際、気付くまではちょっと非効率なコードを書いていました)

忍者ブログ [PR]
ブログ内検索
最近の状況
リンク
カレンダー
02 2024/03 04
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
使用許諾
最新コメント
(08/15)
(05/04)
(03/06)
(03/04)
(09/25)
最新トラックバック
ブログ内検索
最近の状況
リンク
カレンダー
02 2024/03 04
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
使用許諾
最新コメント
(08/15)
(05/04)
(03/06)
(03/04)
(09/25)
最新トラックバック