- ベストアンサー
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; }
- mos21
- お礼率46% (128/273)
- Java
- 回答数3
- ありがとう数4
- みんなの回答 (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つ配列が必要になりますね。 では、頑張ってください。 参考まで。
その他の回答 (2)
- hiroyapapa
- ベストアンサー率45% (17/37)
元のコード 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方向の感覚も沸いてきて、なお良いようにも思います。 参考まで。 でも、まだ私にはこの変換が何を目的とするものかを想像することが出来ません。宜しければ、補足などに書き込んでいただけると...
補足
回答ありがとうございます!!この変換は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)
r.nextInt() ↑の r が問題の部分でしょう。 r は、int型の変数なのではないですか? たぶん、この r は java.util.Random のインスタンス のつもりでしょうが、r は RGB の変数に使われてますからねぇ。。。 <int>.nextInt() と言う事になってしまいます。 ようするに単純な書き間違いって事ですね (^^*
お礼
ありがとうございましたー!!コンパイル出来ましたー^^んでまたわからないことが出来てしまったのですが、このプログラムで実行した場合だと、ランダムに明るさが半減する部分が本当にラインには関係なくランダムになってしまいTVの砂嵐のようになってしまいました。横のラインごとに明るさが半減するようにするにはどうすればよいか、ご存知ではないでしょうか?以前は奇数のラインが半減(偶数部は明るさはそのまま)や偶数ラインが半減(奇数部は明るさそのまま)という形でやっておりました。
関連するQ&A
- 質問です。
1枚の静止画像を、1行おきに、元の色使いのままの行と、明るさ半減した行を合成するというプログラムなのですが。偶数行を半減させるか、奇数行を半減させるかではなくてランダムに行を半減させるにはどうすればよいのでしょうか?RandomクラスやMathクラスを使用すればよいでしょうか? 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 ; }
- ベストアンサー
- Java
- 意味がわかりません
for(int i=0; i < w*h ; i++){ try{ int r = (int)(pixels[i]&0x00ff0000); if (r!=0x00000000){r = ((int)((pixels[i]&0x00ff0000)*90/100)&0x00ff0000);} int g = (int)(pixels[i]&0x0000ff00); if (g!=0x00000000){g = ((int)((pixels[i]&0x0000ff00)*90/100)&0x0000ff00);} int b = (int)(pixels[i]&0x000000ff); if (b!=0x00000000){b = ((int)((pixels[i]&0x000000ff)*90/100)&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){;} } このようなプログラムがあるのですが、何をしているのかがわかりません。 見づらいかもしれませんがどなたかわかる方よろしくお願いします。
- ベストアンサー
- JavaScript
- プログラムについて
javaを使って静止画像にラインをつけて、その奇数ライン画像(偶数ラインは輝度が下がっている画像)と偶数ライン画像(奇数ラインは輝度が下がっている画像)の2枚の画像を1/100秒間隔で交互に表示させ、実際に見ているぶんには普通の静止画像が表示されているというプログラムを作りました。この輝度が下がっているところは奇数ラインと偶数ラインのように決まっているのですが、これを輝度が下がっているところがランダムになるようにとりたいのですがどうるればよいかわかりません... わかる方いましたら何かアドバイスなどお願いします。m(_ _)m for(int i=0; i < w*h ; i++){ try{ int r = (int)(pixels[i]&0x00ff0000); if (r!=0x00000000){r = ((int)((pixels[i]&0x00ff0000)*90/100)&0x00ff0000);} int g = (int)(pixels[i]&0x0000ff00); if (g!=0x00000000){g = ((int)((pixels[i]&0x0000ff00)*90/100)&0x0000ff00);} int b = (int)(pixels[i]&0x000000ff); if (b!=0x00000000){b = ((int)((pixels[i]&0x000000ff)*90/100)&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){;} } これがそのプログラムの、交互に表示している場所だと思うのですが。
- ベストアンサー
- Java
- プログラムで
以前も似たような質問をしたのですが、いろいろとやってみたのですがわからなくてまた質問しました。現在、次のようなプログラムを書いています。 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++){ 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((ra.nextInt()%2)!=0) { epixels[i] = 0xff000000| r | g | b ; uepixels[i]=pixels[i]; } else { epixels[i] = pixels[i]; uepixels[i] = 0xff000000| r | g | b ; } (Exception ex){;} } しかし、これですとiが1進む毎にランダムに真または偽をとってしまうため、実際に動かしてみた所「砂嵐」のように画像が表示されました。このランダムにとるのを、1ライン目はそのままの明るさで2ライン目は明るさ半減していて3ライン目も明るさ半減していて・・・といった感じにライン毎にランダムに「そのままの明るさのライン」か「明るさが半減しているライン」かをとるように改良するにはどうしたらいいでしょうか?お願いします。
- ベストアンサー
- Java
- プログラムで
次のtry文がよくわからなくて困っています。わかる方いましたら解説お願いします。 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){;} }
- ベストアンサー
- Java
- 意味がわかりません
javaのプログラムでこのようなものがあったのですがよくわかりません、解説をお願いします。配列変数pixelsのi番目の値の何をr,g,bに入れているのかがよくわかりません。わかる方いましたら、お願いします。 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); }
- ベストアンサー
- Java
- javaの配列部分ででエラーがでます。
javaの配列部分ででエラーがでます。 マインスイーパを作っており爆弾の位置を決めるところでエラーの原因がわからず困っています。 9×9で、 ランダムでかぶらないように10個の爆弾を置くプログラムを作りたいです。 Random rnd=new Random(); int[][] mine=new int[8][8]; for(int i=0;i<=9;i++){ int yoko=(rnd.nextInt()>>>1)%9; int tate=(rnd.nextInt()>>>1)%9; if(mine[yoko][tate]!=10)mine[yoko][tate]=10; //爆弾があるところは10 else i--; } よろしくお願いします。
- ベストアンサー
- Java
- ピクセル情報について
画像を読み込んでピクセル情報を取得して、 R.G.B値を操作しようとして次の様にプログラムを組みました。 (抜粋ですみません) pg = new PixelGrabber(img1,0,0,width,height,pixel,0,width); try { pg.grabPixels(); System.out.println("pg ok"); //デバッグ表示用 } catch(InterruptedException e) { System.out.println(e); } for(int i=0; i<width*height; i++) { int pix = pixel[i]; int red = 0xff & (pix >> 16); int green = 0xff & (pix >> 8); int blue = 0xff & pix; red += uppoint; green += uppoint; blue += uppoint; pixel[i] = (0xff000000 | red<<16 | green<<8 | blue); } 旨く動けばR.G.B値にuppoint分の数値が足されるはずなんですが、エラーがでてしまいます。 何処が悪いのか判らなくて困っています。 どなたか教えていただけないでしょうか?
- 締切済み
- Java
- 画像の抽出
今、VB2008を用いて、原画像と原画像に落書きをした画像の2枚を用いて、 落書きのみを抽出するプログラムを作っているのですが、 RGBの演算がどうも上手く出来ません。 コードは Dim r1#, g1#, b1#, r2#, g2#, b2#, r3#, g3#, b3# Dim i%, j%, nx%, ny% Dim col1, col2 As Color '略 For j = 0 To ny - 1 For i = 0 To nx - 1 col1 = bmp1.GetPixel(i, j)'落書きした画像 r1 = col1.R g2 = col1.G b3 = col1.B col2 = bmp2.GetPixel(i, j)'落書き前の原画像 r2 = col2.R g2 = col2.G b2 = col2.B r3 = r1 - r2 g3 = g1 - g2 b3 = b1 - b2 bmp3.SetPixel(i, j, Color.FromArgb(Int(r3), Int(g3), Int(b3)))'落書きのみ抽出された画像の書き込み Next Next Form1.Picturebox1.Image = bmp3 としてみたのですが、gやbの値が - になってしまい、エラーが出て しまいます。If(g3<255) then g3 =255 などと記載してみたのですが上手くいきませんでした。 どこを修正、加筆すればうまく抽出が出来る様になるのでしょうか。
- ベストアンサー
- Visual Basic
お礼
ありがとうございました^^意見を参考にしながらがんばります。わかんらないことがあったら質問するかもしれませんが、その時はまたお願いできたらと思います。本当にありがとうございましたー!!