| 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);
以下は前の時と同じです。あとは、ピクセルデータについてですね。
これは 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 ) ;
}
・・・・・。| 戻る |