Java2では、任意のピクセル形式を指定出来るフレームバッファを持ったBufferedImageクラスが新設されました。これにより、バッファ内のピクセルを配列の要素として直接参照し処理を行える上にBufferedImageにはGraphic2で描画を行う事も可能です。
ちょうどWin32のDIBSectionのような感じですね。今回は、Win32の32bitDIBSectionと同様のピクセル形式(xBGRの32ビット)でJavaのBufferedImageを作ってピクセルの操作を試してみる事にしましょう。
BufferedImageの構造
BufferedImageは、rasterとColorModelから成っています。ただ、ピクセルの読み書きをするだけなら、コンストラクタでイメージの形式を指定してBufferedImageを作りrasterを通してピクセル列のバッファを読み書きすれば良いみたいですね。ColorModelはImage内のピクセルを色成分やアルファ値に変換するもので、イメージデータを管理するrasterオブジェクト内のDataBufferがピクセル列を保持しています。
BufferedImageには、いくつかのオーバーロードされたコンストラクタがありますが、今回は大きさとイメージの形式を指定するコンストラクタでBufferedImageオブジェクトを作りました。
biImg=new BufferedImage(256,256,BufferedImage.TYPE_INT_BGR);
コンストラクタの第3引数がイメージの形式です。今回は、BGRの32ビットとするのでBufferedImageクラスのstaticフィールドで定義されているBufferedImage.TYPE_INT_BGRを指定します。BufferedImageが出来たら、ピクセルを読み書きするためのraster(WritableRaster)をgetRaster()で取得。
WritableRaster ras=biImg.getRaster();
ピクセル列にアクセスするには、WritableRasterのgetDataBuffer()を呼び出します。今回は、各ピクセル32ビットなのでDataBufferIntのgetData()やgetElem()で読み出し、setElem()で書き込む、という感じですかね。ポインタが使えないのでちょっとまわりくどい感じですが、一応一通りの操作は出来るので何とかなるでしょう。
次に、BufferedImageのcreateGraphics()でイメージに描画するためのGraphics2Dオブジェクトも作っておきます。
Graphics2D gg=biImg.createGraphics();
これで、ggに対して文字列や図形の描画などの処理が行えるようになります。
ピクセルのアクセスと描画
以上の処理で、BufferedImageオブジェクト、ピクセル列(フレームバッファ)へのアクセス手段、描画処理用Graphics2Dオブジェクトが出来ました。通常のイメージ処理なら、これだけあればとりあえず可能ですね。さっそく、ピクセル列に書き込んでみましょう。ピクセル列の読み書きは、イメージから取得したWritableRasterオブジェクトrasのgetDataBuffer()で返されるデータバッファに対して行います。
for (int i=0;i<256;i++) for (int j=0;j<256;j++) ras.getDataBuffer().setElem(0,i*256+j,(j<<16)+(i<<8)+i);
この例では、setElemの第2引数が書き込む位置、第3引数が書き込む値になっています。書き込む位置は先頭からのオフセットで、今回のビットマップは横幅が256ピクセルですからi*256+jで(j,i)のピクセルにアクセスできるわけですね。第1引数は読み出すバンクですが、今回はピクセルが最初のバンクにまとめられているはずなので、0を指定しておきます。
次に、Graphics2Dオブジェクトggで文字列を書いてみましょう。これは、単に
gg.drawString("Test",64,64);
とするだけです。そして、作成したイメージはコンポーネントの描画メソッドで、
public void paint(Graphics g) { Graphics2D g2=(Graphics2D)g; g2.drawImage(biImg,16,24,this); }
のような感じでコンポーネント上に描画すれば画面に表示できます。
プログラム
今回はJava2アプリケーションです。ソースのファイル名をbufimg.javaとしてJDK1.2でコンパイル・実行してみてください。JavaアプリケーションのウインドウがFrameのサブクラスとして生成され、その中にイメージが表示されます。