- PR -

forループ

投稿者投稿内容
NaN
会議室デビュー日: 2005/04/03
投稿数: 10
投稿日時: 2005-04-03 11:49
C++の自作画像解析&加工プログラムを java(SWT)に移植したことがあります。
性能はほぼ同等でした。
単純な fill block 処理でも java の方が早いことがあります。
hotspot の恩恵でしょうか。
メンテは java の方がはるかに楽ですから、以降、C++ の方はほったらかしです。

ただ、もし pixel を操作するなら決して pixel をクラスにしないこと。
クラスにするとガーベージコレクションに負荷がかかりすぎます。
プリミティブ(たとえば int)で扱いましょう。
当初、これでなかなか性能が出ず、あきらめかけました。

元の C プログラムがインラインアセンブラばりばりでもない限り、
DNIを使用せずとも、十分 java に移植可能と思います。
kosuke
常連さん
会議室デビュー日: 2005/03/24
投稿数: 48
投稿日時: 2005-04-03 12:38
引用:

かつのりさんの書き込み (2005-04-03 11:36) より:
私もJavaのグラフィックは詳しくないですが、
java.awt.image.VolatileImageというクラスがあり、
Windowsなら直接DirectXのVRAMとのやり取りが可能らしいです。
調べてみてはいかがでしょうか。

ちなみにJavaは遅いというイメージがありますが、
http://www001.upp.so-net.ne.jp/y_yutaka/labo/math_algo/calcbench.html
を参考にしてみてください。
演算処理に関しては、極端に遅いということはないと思われます。




確かに極端に遅くはないようです。
はじめて知りました。ありがとうございます。
kosuke
常連さん
会議室デビュー日: 2005/03/24
投稿数: 48
投稿日時: 2005-04-03 12:41
引用:

未記入さんの書き込み (2005-04-03 11:49) より:

ただ、もし pixel を操作するなら決して pixel をクラスにしないこと。
クラスにするとガーベージコレクションに負荷がかかりすぎます。
プリミティブ(たとえば int)で扱いましょう。
当初、これでなかなか性能が出ず、あきらめかけました。




返信ありがとうございます。
すみませんが上記の引用部をもう少し詳しくご教示いただけないでしょうか?
NaN
会議室デビュー日: 2005/04/03
投稿数: 10
投稿日時: 2005-04-03 13:19
ピクセルに限りませんが、画像処理で発生しがちな「きつい」ループ中で
回避可能な、代替手段のある new が起こらないように気をつける、ということです。

SWT の ImageData は24ビット画像の場合は
int p = imaga_data.getPixel( x, y );
で 0x00bbggrr 形式のピクセルデータが返却されます。
(java2D とかは使ったことがありませんがきっと似たようなのがあるでしょう。)

この p を扱うために
public class CPixel {
int pixel;
プロパティいろいろ
public CPixel( int pixel ){ this.pixel = pixel; }
メソッドいろいろ
}
というようなクラスは有用かもしれませんが、きついループ中では使用
しないようにしよう...ということです。


[ メッセージ編集済み 編集者: 未記入 編集日時 2005-04-03 13:42 ]
kosuke
常連さん
会議室デビュー日: 2005/03/24
投稿数: 48
投稿日時: 2005-04-03 18:17
ピクセル値の取得はint型の配列colorData[]を用意して

for(int loop2 = 0; loop2 < image.getHeight(this); loop2++) {
for(int loop1 = 0; loop1 < image.getWidth(this); loop1++) {
raster.getPixel(loop1,loop2,colorData);
}
}

としました。しかし、ピクセルの編集において

PixelColor[0]=255;
PixelColor[1]=0;
PixelColor[2]=0;
for(int loop2 = 0; loop2 < image.getHeight(this); loop2++) {
for(int loop1 = 0; loop1 < image.getWidth(this); loop1++) {
  raster.setpixel(loop1,loop2,PixelColor);
}
}

とすると全体が赤になるのですが、配列PixelColorの値を変えると
黒になってしまいます。
どこか間違っているでしょうか?
NaN
会議室デビュー日: 2005/04/03
投稿数: 10
投稿日時: 2005-04-03 19:04
引用:

とすると全体が赤になるのですが、配列PixelColorの値を変えると
黒になってしまいます。



ハンドルを NaN としました。よろしく。

PixelColorを何色にしたのですか?
どうやってその色にしたのですか?
が、わらないとなんとも...コードを。

raster は java.awt.image.WritableRaster
image は java.awt.Image or java.awt.image.BufferedImage
なのでしょうね。

setPixelでの指定ピクセル値は int配列なんですね。
ループ中で配列を取り直したりさえしなければ性能は大丈夫でしょう。

C との性能比較を私も知りたいです。


[ メッセージ編集済み 編集者: NaN 編集日時 2005-04-03 19:09 ]
kosuke
常連さん
会議室デビュー日: 2005/03/24
投稿数: 48
投稿日時: 2005-04-03 19:58
引用:

PixelColorを何色にしたのですか?
どうやってその色にしたのですか?
が、わらないとなんとも...コードを。


説明不足で申し訳ありません。

 PixelColor[0]=255;
 PixelColor[1]=0;
 PixelColor[2]=0;

のときは(R,G,B) = (255,0,0)となっているのですが、例えば

 PixelColor[0]=0;
 PixelColor[1]=255;
 PixelColor[2]=0;

とすると(R,G,B) = (0,0,0)となってしまいます。
どうも(255,0,0)しか設定できないようなのですが...

引用:

raster は java.awt.image.WritableRaster
image は java.awt.Image or java.awt.image.BufferedImage
なのでしょうね。

setPixelでの指定ピクセル値は int配列なんですね。


その通りです。コードを以下に記載します。

private BufferedImage proces(BufferedImage image) {
BufferedImage temp = new BufferedImage(image.getWidth(this),
image.getHeight(this),
BufferedImage.TYPE_INT_ARGB);
WritableRaster raster = image.getRaster();
int colorData[] = new int [4];
int PixelColor[] = new int [4];
//色の設定
PixelColor[0] = 255;
PixelColor[1] = 0;
PixelColor[2] = 0;

for(int loop1 = 0; loop1 < image.getHeight(this); loop1++) {
for(int loop2 = 0; loop2 < image.getWidth(this); loop2++) {
raster.getPixel(loop2,loop1,colorData);
raster.setPixel(loop2,loop1,PixelColor);
}
}

return temp;
}
NaN
会議室デビュー日: 2005/04/03
投稿数: 10
投稿日時: 2005-04-03 21:36
PixelColor[0] = 0;
PixelColor[1] = 255;
PixelColor[2] = 0;
for(int loop1 = 0; loop1 < image.getHeight(this); loop1++) {
for(int loop2 = 0; loop2 < image.getWidth(this); loop2++) {
raster.getPixel(loop2,loop1,colorData);
raster.setPixel(loop2,loop1,PixelColor);
}
}

で緑にならないということですね。
なんででしょうね。
まちがって PixelColor[1] = 256; なんてことはありませんよね。

image.getHeight(this); image.getWidth(this); の this は
ImageObserverをimplementsしているんでしょうか?
Applet ですか?

image.getHeight(); image.getWidth(); で、どうでしょう?

ところで、どうやってデバックしています?
最近の定番は eclipse ですが、使っています?
getPixel setPixel で止めて colorData や PixelColor の値をチェックしたり、
2重の for ループが予想通りの回数回っているかチェックしたり、
setPixel 後に getPixel して RGB を System.out.plintln してみたり...


[ メッセージ編集済み 編集者: NaN 編集日時 2005-04-03 21:53 ]

スキルアップ/キャリアアップ(JOB@IT)