忍者ブログ
[153] [152] [151] [150] [149] [148] [146] [147] [145] [144] [143]

DATE : 2024/04/20 (Sat)
×

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


DATE : 2006/09/05 (Tue)

アルファチャンネルを追加した BufferedImage を作成する」で掲載したコードは、私が開発していたアプリケーションに組み込まれていたコードをリファクタリングしたものです。

初めは、それほど長いコードでもなかったのでリファクタリングせずに掲載しようと思っていたのですが、リファクタリングすると「処理手順」に沿ったコードになったので、とても面白く感じました。

そこで、リファクタリングを行った記録を書き残しておこうと思い立ちました。できれば、掲載したコードよりもさらに再利用しやすい形にリファクタリングを進めていこうと思います。

ちなみに、リファクタリング前のコードは次の通りです(Subversion のリポジトリから引っ張りだしてきました)。

なお、一応動作はしますが、リファクタリング後のコードと比べると、細かい部分で間違いが含まれています。

なお、import 文などは省略しています。また、「...」は省略を表します。

/**
 * 指定の画像にアルファチャンネルを加えます。
 * 
 * @param image アルファチャンネルを加える画像
 * @return アルファチャンネルを加えた画画像
 */
private static RenderedImage addAlphaChannel(RenderedImage image) {
	// 対象画像の大きさ
	int width = image.getWidth();
	int height = image.getHeight();
	// 対象画像のカラースペース
	ColorSpace sourceColorSpace = image.getColorModel().
		getColorSpace();
	// アルファチャンネルのあるカラーモデル
	ColorModel destColorModel = new ComponentColorModel(
		sourceColorSpace, true, false,
			Transparency.BITMASK, DataBuffer.TYPE_BYTE);
	WritableRaster destRaster = destColorModel.
		createCompatibleWritableRaster(width, height);
	// 色成分のバンド番号の配列
	int[] colorBandList = getColorBandList(destRaster.getNumBands());
	// 色成分のみの WritableRaster
	WritableRaster colorRaster = destRaster.
		createWritableChild(0, 0, width, height,
			0, 0, colorBandList);
	WritableRaster alphaRaster = destRaster.
		createWritableChild(0, 0, width, height, 0, 0,
			new int[]{destRaster.getNumBands() - 1});
	// 可視領域を表すアルファ成分のみの Raster
	WritableRaster visibleMaskRaster =
		createVisibleAlphaRaster(image);
	
	colorRaster.setRect(image.getData());
	alphaRaster.setRect(visibleMaskRaster);
	
	return new BufferedImage(destColorModel, destRaster,
		false, null);
}

/**
 * 可視部分のアルファ成分のみを持つ WritableRaster を生成します。
 * 
 * @param source 生成対象の画像
 * @return 可視部分のアルファ成分のみを持つ WritableRaster
 */
private static WritableRaster createVisibleAlphaRaster(
		RenderedImage source) {
	// 画像の大きさ
	int width = source.getWidth();
	int height = source.getHeight();
	// SampleModel
	SampleModel sampleModel = new BandedSampleModel(
		DataBuffer.TYPE_BYTE, width, height, 1);
	WritableRaster raster = Raster.createWritableRaster(
		sampleModel, new Point(0, 0));		
	int[] alphaSample = new int[width * height];
	
	// データの最大値を設定(アルファ成分を最大にする)
	Arrays.fill(alphaSample, 0xff);
	raster.setSamples(0, 0, width, height, 0, alphaSample);
	
	return raster; 
}

/**
 * 指定のバンド数から、アルファ成分を除いたバンド番号の配列を
 * 返します。
 * 
 * @param numBands バンド数
 * @return アルファ成分を除いたバンド番号の配列
 */
private static int[] getColorBandList(int numBands) {
	int[] bands = new int[numBands - 1];
	
	for (int i = 0; i < bands.length; i++) {
		bands[i] = i;
	}
	
	return bands;
}

上のメソッド群は、 ImageProcessor クラスに含まれているメソッドで、ImageProcessor 内部で使用されています。

(;^ω^)正直なところ、あまり見直したくないコードですね。あちこちにコメントがある割には、解読にはそれなりの時間がかかりそうです。

次回から、このコードをリファクタリングしていきます。

つづきます

PR
●この記事にコメントする
お名前
タイトル
文字色
メールアドレス
URL
コメント
パスワード
●この記事へのトラックバック
この記事にトラックバックする:
忍者ブログ [PR]
ブログ内検索
最近の状況
リンク
カレンダー
03 2024/04 05
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
使用許諾
最新コメント
(08/15)
(05/04)
(03/06)
(03/04)
(09/25)
最新トラックバック
ブログ内検索
最近の状況
リンク
カレンダー
03 2024/04 05
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
使用許諾
最新コメント
(08/15)
(05/04)
(03/06)
(03/04)
(09/25)
最新トラックバック