• ベストアンサー

int型について

1枚の静止画像の明るさを、1行おきにではなくてランダムに、元の色使いのままの行と、明るさを半減した行を持つという画像を2枚作成したいのですが、次のプログラムの記述ではif((r.nextInt()%2)!=0){の部分でintは間接参照できません。というエラーが出てしまいました。なぜでしょうか?わかる方いましたらお願いします。 先に記述してあるプログラムを後で記述したプログラムに改良したところエラーが起こってしまいました。 こちらが改良前で if((((w+i)/w)%2)!=0){ epixels[i] = 0xff000000| r | g | b ; uepixels[i]=pixels[i];} else {    epixels[i] = pixels[i];uepixels[i] =  0xff000000| r | g | b ;} こちらが改良後です。 if((r.nextInt()%2)!=0){ epixels[i] = 0xff000000|r|g|b; uepixels[i] = pixels[i]; } else{ epixels[i] = pixels[i]; uepixels[i] = 0xff000000|r|g|b; }

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

#2です。 補足いただきましてありがとうございました。 なかなかおもしろいことをやっていますね。 わたくしもちょっと補足させていただきますね。 ★横のライン単位に切り替える手法 #2で書いた回答がちょっと不親切かもしれないと思い追記します。 if(半減するかしないか) を、if(y%2 == 0)としたら改造前の条件と一致します。 ランダムにする手法はもう習得すみですね。 ★「2、3枚」とおっしゃっておられるので、特に3枚以上にも対応しやすくするためにも、#2で回答したように iによる単一ループは、y方向とx方向による二重ループに書き直したほうが改造しやすいでしょう。 ついでながら、冗長なコードもとっぱらったら、以下のようになります。 for(int y=0; y<h; y++) { //縦のループ    if(y%2 == 0) { //ここをランダムに      for(int x=0; x<w; x++) { //横のループ        int r = ( (pixels[y*w+x]&0x00ff0000)>>1 ) & 0x00ff0000;    int g = ( (pixels[y*w+x]&0x0000ff00)>>1 ) & 0x0000ff00;    int b = ( (pixels[y*w+x]&0x000000ff)>>1 );    epixels[y*w+x] = 0xff000000|r|g|b;    uepixels[y*w+x] = pixels[y*w+x];   }  } else {   for(int x=0; x<w; x++) { //横のループ        int r = ( (pixels[y*w+x]&0x00ff0000)>>1 ) & 0x00ff0000;    int g = ( (pixels[y*w+x]&0x0000ff00)>>1 ) & 0x0000ff00;    int b = ( (pixels[y*w+x]&0x000000ff)>>1 );    epixels[y*w+x] = pixels[y*w+x];    uepixels[y*w+x] = 0xff000000|r|g|b;   }  } } まだ冗長コードはありますけど、 ・おきない例外を捕捉しない...try-catchをとる。 ・r,g,bの計算に現れる、代入-ノンゼロ判定-再計算はしなくても上記コードだけで結果は同じ。 ・0.5を掛けるより、1ビットシフトしたほうが多分速い。 ★実際に3枚に分けるには... ・stateをboolean(2値変数)から3値とれる変数にする必要があるでしょう。 ・epixels[], uepixels[]のほかに、もう1つ配列が必要になりますね。 では、頑張ってください。 参考まで。

mos21
質問者

お礼

ありがとうございました^^意見を参考にしながらがんばります。わかんらないことがあったら質問するかもしれませんが、その時はまたお願いできたらと思います。本当にありがとうございましたー!!

その他の回答 (2)

回答No.2

元のコード if((((w+i)/w)%2)!=0) をご理解されていないうちに、先に進もうとなさっているように思います。 私も、このコードを見たときは何が何だかよくわかりませんでした。 絵を描いてみましょう。   x方向は wピクセル  ----------- y|○○○○○○○○○○ 方|○○○○○○○○○○ 向|○○○○○○○○○○ は|○○○○○○○○○○ h|○○○○○○○○○○ ピ|○○○○○○○○○○ ク|○○○○○○○○○○ セ|○○○○○○○○○○ ル|○○○○○○○○○○ 確か、for(int i=0; i<w*h; i++)のループでしたよね。 変数iは左隅から横に進み、1ライン分いくと下のラインの左端へ、って感じですよね。 先のif文の中の条件式はiがw進む毎に真偽が入れ替わるようになっているのです。 それでは、あなたが改造したコードのif文の中の条件式の真偽は、どうですか? iが1進む毎にランダムに真または偽ですよね。 その結果が「砂嵐」です。 大変失礼な言い方かもしれませんが、前半部分も含めて読みにくいコードであるがゆえ、ご理解の進捗も悪いのかなぁと思います。 以下のように少し解りやすく書き直すとどうでしょう。 これが「最高」というつもりはありません。 for(int y=0; y<h; y++) { //縦のループ    if(半減するかしないか) { //ここをランダムに      for(int x=0; x<w; x++) { //横のループ        epixels[y*w+x] = 0xff000000|r|g|b;    uepixels[y*w+x] = pixels[y*w+x];   }  } else {   for(int x=0; x<w; x++) { //横のループ        epixels[y*w+x] = pixels[y*w+x];    uepixels[y*w+x] = 0xff000000|r|g|b;   }  } } 蛇足ながら、pixelsやepixels,uepixelsを二次元配列になさると、X方向Y方向の感覚も沸いてきて、なお良いようにも思います。 参考まで。 でも、まだ私にはこの変換が何を目的とするものかを想像することが出来ません。宜しければ、補足などに書き込んでいただけると...    

mos21
質問者

補足

回答ありがとうございます!!この変換は1枚の画像を2枚の画像(奇数ライン画像と偶数ライン画像)を取得します。それぞれ奇数ライン画像では偶数ラインが、偶数ライン画像では奇数ラインの明るさが半減している。そしてその2枚の画像を交互に表示することにより1枚の画像として表示するというプログラムです。プログラムの全体を記述しますね。少し長いですけど。(^^; import java.applet.*; import java.awt.*; import java.awt.image.*; public class na3 extends Applet implements Runnable { Thread thread; Image img,eimg,uneimg,buffer; boolean state=true; int dly=10; MediaTracker mt = new MediaTracker(this); Toolkit tk = Toolkit.getDefaultToolkit(); public void init() { byte [] imagedata = {-1, -40, -1, -32, 0,・・・ ・・・ -85, 127, 98, -}; //280行くらい img = Toolkit.getDefaultToolkit().createImage(imagedata); mt.addImage( img, 0 ); try{mt.waitForAll();}catch( InterruptedException e ){} int w = img.getWidth(this); int h = img.getHeight(this); int[] pixels = new int[w * h]; int[] epixels = new int[w * h]; int[] uepixels = new int[w * h]; int scan = w; int offset = 0; PixelGrabber pg = new PixelGrabber(img,0,0,w,h,pixels,0,scan); try{pg.grabPixels();}catch(InterruptedException e){;} for(int i=0; i < w*h ; i++){ try{ int r = (int)(pixels[i]&0x00ff0000); if (r!=0x00000000){r = ((int)((pixels[i]&0x00ff0000)*0.5)&0x00ff0000);} int g = (int)(pixels[i]&0x0000ff00); if (g!=0x00000000){g = ((int)((pixels[i]&0x0000ff00)*0.5)&0x0000ff00);} int b = (int)(pixels[i]&0x000000ff); if (b!=0x00000000){b = ((int)((pixels[i]&0x000000ff)*0.5)&0x000000ff);} if((((w+i)/w)%2)!=0){epixels[i] = 0xff000000| r | g | b ;uepixels[i]=pixels[i];} else {epixels[i] = pixels[i];uepixels[i] = 0xff000000| r | g | b ;} }catch(Exception ex){;} } eimg = createImage( new MemoryImageSource( w, h, epixels, 0, scan )); uneimg = createImage( new MemoryImageSource( w, h, uepixels, 0, scan )); } public void start() {thread = new Thread(this);thread.start();} public void stop() { try { thread.sleep(1000); } catch(InterruptedException e){} } public void update(Graphics g) {paint(g);} public void paint(Graphics g){ if(state){buffer=eimg;} else {buffer=uneimg;} g.drawImage(buffer,0,0,null);state = !state;} public void run() { try {mt.waitForAll();}catch (InterruptedException e) {return;} while( true ) {repaint();try {Thread.sleep(dly);} catch (InterruptedException e) {}} } } 以上がプログラムです。このプログラムを、取得する画像が奇数ライン画像と偶数ライン画像の2枚ではなくてラインをランダムに取るような画像を2、3枚取得するように改良したいのです(^^;

  • takaP-
  • ベストアンサー率79% (83/105)
回答No.1

r.nextInt() ↑の r が問題の部分でしょう。 r は、int型の変数なのではないですか? たぶん、この r は java.util.Random のインスタンス のつもりでしょうが、r は RGB の変数に使われてますからねぇ。。。 <int>.nextInt() と言う事になってしまいます。 ようするに単純な書き間違いって事ですね (^^*

mos21
質問者

お礼

ありがとうございましたー!!コンパイル出来ましたー^^んでまたわからないことが出来てしまったのですが、このプログラムで実行した場合だと、ランダムに明るさが半減する部分が本当にラインには関係なくランダムになってしまいTVの砂嵐のようになってしまいました。横のラインごとに明るさが半減するようにするにはどうすればよいか、ご存知ではないでしょうか?以前は奇数のラインが半減(偶数部は明るさはそのまま)や偶数ラインが半減(奇数部は明るさそのまま)という形でやっておりました。

関連するQ&A