プログラムdeタマゴ

nodamushiの著作物は、文章、画像、プログラムにかかわらず全てUnlicenseです

int,byte配列からBufferedImageを作成する

画像のint,byte配列データを直接弄りたいときは、BufferedImageの持つWritableRasterからDataBufferを取り出して、クラスによってDataBufferByteかDataBufferIntに変換し、データを取り出す。


何かクールじゃないよね。BufferedImageが用意してくれた配列を私が弄るなんて。

むしろそのデータ、私に用意させろ。



というわけで、JavaDoc追いかけてみたらできた。
ARGB画像よりもbyte配列のグレー画像を作る方に結構戸惑った。


こんな変なことやりたい奴ってそんなにいないのか、探し方が下手だったのか、ググっても見つからなかったんだよね。(追記 *1
きっとこの記事は、私みたいな極めて少数の変態に大いなる貢献をすると信じてやまない。あ、おまわりさん、画面の前のこの人です。

/**
 * aRGB画像を作成します
 * @param data イメージデータ
 * @param width 画像幅
 * @param height 画像高さ
 * @param alphaMask 
 * 画素データからアルファ値を取り出すためのマスク。
 * @param redMask 画素データから赤を取り出すためのマスク
 * @param greenMask 画素データから緑を取り出すためのマスク
 * @param blueMask 画素データから青を取り出すためのマスク
 * @return dataを保持するBufferedImage
 */
public static BufferedImage createImage(int[] data,int width,int height,
		int alphaMask,int redMask,int greenMask,int blueMask){
	int[] mask = {redMask,greenMask,blueMask,alphaMask};
	DataBuffer buffer = new DataBufferInt(data, width*height);
	WritableRaster raster = Raster.
			createPackedRaster(buffer,width,height,width,mask,new Point());
	ColorModel model = 
			new DirectColorModel(32, redMask, greenMask, blueMask, alphaMask);
	return new BufferedImage(model, raster, false, null);
}
	
/**
 * グレー画像を作成します
 * @param data イメージデータ
 * @param width 画像幅
 * @param height 画像高さ
 * @return dataを保持するBufferedImage
 */
public static BufferedImage createImage(byte[] data,int width,int height){
	DataBuffer buffer = new DataBufferByte(data, width*height);
	WritableRaster raster = Raster.
			createInterleavedRaster(buffer, width, height, width,
					1,new int[1], new Point());
	ColorModel model = new ComponentColorModel(
			ColorSpace.getInstance(ColorSpace.CS_GRAY), false, false, 
			Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
	return new BufferedImage(model, raster, false, null);
}

public static void main(String[] args) {
	int width = 100,height=100;
	byte[] data = new byte[width*height];
	BufferedImage img = createImage(data, width, height);
	Arrays.fill(data, (byte)0x33);
	JFrame f = new JFrame();
	JLabel l = new JLabel(new ImageIcon(img));
	f.add(l);
	f.pack();
	f.setDefaultCloseOperation(3);
	f.setVisible(true);
}

*1:英語でググってみたらわりと普通に見つかった
Creating a Buffered Image from an Array of Color-Indexed Pixel Values

あと、関数名で検索かけてみたら何個か参考になるページが見つかったのでリンクを張っておきます。
createPackedRaster
createInterleaveRaster
iSight を Java でキャプチャしてみる逃避
Cognaxon - WSQ Image Library - important notes for Sun Java developers