JavaTips  

Javaのテクニックなどです。

  Javaの高速化    
  Javaの最小化?    
  MomoryImageSource   イメージをいじくる。
       
       
       
       
       

 

  戻る  

  Javaの高速化  

方法1。
なんでもかんでも final 宣言する。(^^;;
例えば、class自体やそのメンバ関数なんかをfinal宣言してやる。
5%くらい速くなります。

方法2。
ひとつのメソッドにゴチャゴチャとコードしないで、細かく分けておく。
速くなる理由は良くわかりませんが、上手くすれば10%以上速くなります。(^^;;

方法3。
計算にMathクラスをできるだけ使わない。
あれは遅いです。(^^;;

他にはビット演算を使った高速化や、どこがメインの処理で重いのか確認してそこを高速化するなど・・・当たり前?(^^;;


  Javaの最小化?  

「1k・Javaプログラムコンテスト」ってのがありまして、それに一応「1kトンネルエフェクト」なるものを作ってみました。
その時に発見した classファイルのサイズ縮小方法などを。

方法1。
JDK1.2を使う。
これだけでサイズが小さくなります。

方法2。
メソッドは1行で書く。(^^;;
Javaでは classファイルに行数が保存されます。
改行を無くして1行にすると行数の保存サイズ分だけサイズが減ります。ホントだよ。(^^;;
例えば、

public void paint(Graphics g){g.setColor(Color.red);g.drawString("Hey!",0,10);}

ってな感じです。
・・・・だからホントだって。(^^;;


  MemoryImageSource  

Javaでデモなんかを作ろうとするときには、まず、これの恩恵を受けることになるでしょう。まぁ、Java2環境になれば使わなくなりそうですけど・・・。

MemoryImageSourceとは、int[] pixなどのピクセルデータからイメージを作るクラスです。JDK1.0.2から使えるそうです。(^^;;

イメージからピクセルデータを取り出す時には、PixelGrabberクラスを使います。(PixelGrabberを参照)

使用例

MemoryImageSource ms = new MemoryImageSource(image_width,image_height,pix,0,image_width);
Image image = createImage(ms);

これで image にピクセルデータ pix の内容で image_width,image_height の大きさのイメージが入ります。
0 となっているのはオフセットの値です。うまく使う方法がありそうですが・・・。
最後の image_width はイメージの横ラインのドット数です。これを変化させても面白いですが、配列の外を参照しないように。(^^;;

人によっては、
g.drawImage(createImage(new MemoryImageSource(・・・)),0,0,this);
などと描画するたびにMemoryImageSourceを生成することがあります。

個人的には、

private MemoryImageSource ms;
private Image image;

public void init(){
   ms = new MemoryImageSource(・・・);
   ms.setAnimated(true);
   image = createImage(ms);
}
public void run(){
   ・・・
   while(・・・){
      anime();
      ms.newPixels();
      repaint();
   }
}
public void paint(Graphics g){
   g.drawImage(image,0,0,this);
}

って使い方の方が余分なガーベッジしなそうでいいと思います。
setAnimated()ってのは「MemoryImageSourceでアニメーションしますよ」ってときに唱える呪文。
これと newPixels()で image が更新されてアニメーションします。
他に、setFullBufferUpdates(boolean)ってのもあって、これをtrueにしておくと、pixが更新されたら自動的に再描画してくれます。
もっとも、

public void paint(Graphics g){
   g.drawImage(createImage(new MemoryImageSource(・・・)),0,0,this);
   System.gc();
}

と、毎描画後にガーベッジしてしまえば問題ないと思うので、
こっちの方がいいかも?(^^;;

んでは、インデックスカラーでMemoryImageSourceを使う方法を。

インデックスカラーってのは要するに256色のパレットを使ってイメージを作るものです。
ちょいと違うけど「jpeg」と「gif」みたいなもの・・・・か?(^^;;
扱うのは int[] pix ではなく byte[] pix になります。当たり前?
で、MemoryImageSourceを作る前にちょいと準備が要ります。
PixelGrabberで byte[] pix にインデックスのピクセルデータを入れるのも必要ですが、
IndexColorModelってものが必要になります。
これはその名前の通りに256色の色データです。
この色データ(パレット)とその配置データ(インデックス)でMemoryImageSourceを作ります。
ってグダグダ説明するより実際にソースを見た方が早そうですねぇ。(−−;;

PixelGrabber pg = new PixelGrabber(image256,0,0,image_width,image_height,false);
try{ pg.grabPixels(); }catch(InterruptedException e){}
byte[] pix = (byte[])pg.getPixels();
IndexColorModel icm = (IndexColorModel)pg.getColorModel();

MemoryImageSource ms = new MemoryImageSource(image_width,image_height,(ColorModel)icm,pix,0,image_width);
以下は前の時と同じです。
PixelGrabberについてはPixelGrabberの方で説明します。
image256ってのはイメージなんですが、jpegなんかを指定してもできるんでしょうか?誰か確認したら教えてください。(^^;;

あとは、ピクセルデータについてですね。
これは int[] pixの中身についてです。
みれば分かりますが、pixの内容は intです。
Javaのintは16進数で表現すると 0x00000000 から 0xFFFFFFFF と。 この0xFFFFFFFF がそれぞれ「透明度・赤・緑・青」の成分となっています。

0x FF(透明) FF(赤) FF(緑) FF(青)

分かりますかね?(^^;;それぞれの成分はFF、つまり256が最大値となるようになっています。
色の例をあげると、赤(0xFFFF0000)、緑(0xFF00FF00)、青(0xFF0000FF)、黄(0xFF00FFFF)とかになります。
HTMLの色コードを知っている人はすぐに分かりますよね。(#FFFFFF=白とかね。)
ちょいと注意しなければならないのが、透明ってのはいわゆるアルファ値とは違い、半透明にはならないこと。
実際にやってみると分かるのは当たり前だけど、(^^;;なんか歯抜けになっていくだけです。

この各要素を使ってイメージを変化させていきます。
簡単なところで、イメージを明るくしてみましょうか。

for(int i=0;i<image_width*image_height;i++){
//各要素を取り出す
   int color = pix[i];
   int red = ( color & 0x00FF0000 ) >> 16 ;
   int green = ( color & 0x0000FF00) >> 8 ;
   int blue = ( color & 0x000000FF) >> 0 ;

//それぞれに30を加算して、その最大値が256を超えないようにする
   red = ( red + 30 ) & 0x000000FF ;
   green = ( green + 30 ) & 0x000000FF ;
   blue = ( blue + 30 ) & 0x000000FF ;

//更新したデータをイメージのピクセルデータに収める。
   pix[i] = 0xFF000000 | ( red<<16 ) | ( green<<8 ) | ( blue<<0 ) ;
}
・・・・・。
いきなり分からなくなった人多数・・・・。(^^;;
ビット演算関係について説明しないとイケナイなぁ・・・。

  戻る