• ベストアンサー

意味がわかりません

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); }

  • mos21
  • お礼率46% (128/273)
  • Java
  • 回答数2
  • ありがとう数1

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

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

ご理解いただけるかどうか自信はありませんが、頑張ってみますね。 Red値は、0~255の値をとる。16進で表現すると0x00~0xFFですね。 Green値、Blue値も同様。 と、ここでは考えましょう。 参照されているコードに現れる変数それぞれについて、考察します。 bは、int型(32bit幅)の変数であり、0x00000000~0x000000FFにてblue値を格納している模様。(一番下位の1バイトに0~255を入れているのですね。) gは、int型(32bit幅)の変数であり、二番目の下位のバイトに0~255のgreen値を格納している模様。別の言い方をすれば、0~255の値に256を掛けた値を格納しているのですね。もう一つ別のいい方をすれば、0~255の値を左に8bitシフトした値を格納しているのですね。 rは、gと同様ですが、(256*256)を掛けた値を格納していると理解するか、左に16bitシフトした値を格納していると理解するか、あなたの理解しやすい方で理解してください。 この3つの値を、int型(32bit)に一気に詰め込んだものが、pixels[i]ですね。(実際には24bitしか使われませんが) 0x00xxyyzzの、xxがred値、yyがgreen値、zzがblue値となっています。 では、論理積とはなにかは、本で勉強していただくとして、 0x00xxyyzzから、yyやzz部分を00に置き換えて、純粋なxx部分だけを持った値をとりだそうとしたら、 0x00xxyyzz & 0x00FF0000 という演算をおこないます。 結果は、0x00xx0000という値になります。 そして、さらに2で割っていますよね。 xx部分が偶数だったら結果は、0x00tt0000という値になりますが、 奇数であった場合には、0x00tt8000という値になってしまって、気にいりません。 ということで、2で割ったあとに、もう一度0x00FF0000とANDをとって整形しているのです。 私にはこれ以上のことは言えないです。 あなたが2進数に弱いのであれば、演算子 &, |, ~, >>, <<などを中心に勉強いただくとご理解できるものと思います。 参考になれば。

mos21
質問者

お礼

ありがとうございます。すごくよくわかりました^^ これからまた勉強していこうと思いますm(_ _)m

その他の回答 (1)

  • Traja
  • ベストアンサー率19% (107/546)
回答No.1

そのまま説明すれば、 pixels変数と0x00ff0000との論理積をとり、結果がゼロ以外ならば 結果値に0.5を積算した結果を変数rに格納する。以下同様 と言うことになりますが 変数名から推測すると、ピクセル毎のRGB値を取り出し 明るさを半減して、各変数に格納してるんじゃないですか? 変数名がpixels,r,g,bなので推測しましたが、これがx,a,b,cだったら 上段の説明しか出来ないでようね。

mos21
質問者

補足

ありがとうございました。明るさの50%の値を格納してる感じはするのですが、0x00ff0000ってなんですか?あと、論理積をとるというのがわかりません。どういう意味なんでしょうか?(^^;

関連するQ&A

  • 意味がわかりません

    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){;} } このようなプログラムがあるのですが、何をしているのかがわかりません。 見づらいかもしれませんがどなたかわかる方よろしくお願いします。

  • プログラムで

    次の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を使って静止画像にラインをつけて、その奇数ライン画像(偶数ラインは輝度が下がっている画像)と偶数ライン画像(奇数ラインは輝度が下がっている画像)の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
  • ビットマップを直接編集して背景画像を波打たせる

    質問(1) pixelsは一次元配列で1ラインのx方向の要素を左方向や右方向にシフト量sだけ離れた所へコピーすることにより1ラインの画像のピクセルデータをシフト量sだけずらして波打たせる効果を持たせていることは想像つきますが、これではy方向を考慮した全てのラインをずらすことにはなっていない様な感じがします。y方向はどうなっているのですか? 質問(2) int line = y*bmpdata.Stride/4;で4で割っているのは何故ですか? 質問(3) if(s<0){ //左へコピー for(int x=-s; x<BITMAP_W; x++){ if(x+s>=0){ pixels[line+x+s] = pixels[line+x]; } } } でこのif文の中の条件式x+s>=0はint x=-s;→int x+s=0;…;x++により明らかに常に真ではないですか?もし、そうだとしたらこのif文は必要ないのではないですか? 質問(4) } else if(s>0){ //右へコピー for(int x=BITMAP_W; x>=s; x--){ if(x+s<BITMAP_W){ pixels[line+x] = pixels[line+x-s]; } } } } でこのif文の中の条件式x+s<BITMAP_Wの意味が良く分かりません。 質問(5)(6)(7) for(int y=0; y<BITMAP_H; y++){ … int line = y*bmpdata.Stride/4;の意味が良く分かりません。質問(5) … pixels[line+x+s] = pixels[line+x];でlineを加えているのは何故ですか?質問(6) … pixels[line+x] = pixels[line+x-s];でlineを加えているのは何故ですか?質問(7) C言語、C++言語初心者なので分かりやすく教えて下さい。 宜しくお願いします。 プログラムコード(animation.cpp) //ウェーブエフェクト UINT g_wavecount; const int BITMAP_H = 480; const int BITMAP_W = 320; float g_wavelines[BITMAP_H]; //ウェーブエフェクト初期化 void ResetWave(){ g_wavecount = 0; float r=0, rdelta=3.14f/12;//波の数 float waveh = 3;//波の高さ for(int i=0; i<BITMAP_H; i++){ g_wavelines[i] = sinf(r) * waveh; r += rdelta; } } //ウェーブエフェクト描画 void RenderWave(Gdiplus::Bitmap *bmp){ g_wavecount++; int topline = g_wavecount % BITMAP_H; //ビットマップのロック Gdiplus::BitmapData bmpdata; Gdiplus::Status status = bmp->LockBits( &Gdiplus::Rect(0,0,320,480), Gdiplus::ImageLockModeWrite, bmp->GetPixelFormat(), &bmpdata); if(status != Gdiplus::Ok) return; UINT* pixels = (UINT*)bmpdata.Scan0; //←この行から下のコードが全部分からない。 //ビットマップを加工する for(int y=0; y<BITMAP_H; y++){ //シフト量を取得 int s = (int)g_wavelines[(topline+y)%BITMAP_H]; int line = y*bmpdata.Stride/4; //ピクセルコピー if(s<0){ //左へコピー for(int x=-s; x<BITMAP_W; x++){ if(x+s>=0){ pixels[line+x+s] = pixels[line+x]; } } } else if(s>0){ //右へコピー for(int x=BITMAP_W; x>=s; x--){ if(x+s<BITMAP_W){ pixels[line+x] = pixels[line+x-s]; } } } } bmp->UnlockBits(&bmpdata); }

  • 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; }

    • ベストアンサー
    • Java
  • 質問です。

    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
  • カラー画像からグレースケール画像フォーマットの変換

    カラー画像からグレースケール画像フォーマットの変換するプログラムなんですが、いまいち理解できていません。 プログラムはRGB構造体を使ってのものなんですが添削お願いいたします。 #include<stdio.h> #include<stdlib.h> typedef struct _RGB { unsigned char r; unsigned char g; unsigned char b; } RGB; int main(int argc, char *argv[]) { int x, y; unsigned char *in, *out; int i, j, Magic, level; unsigned char tmp[255]; RGB **pixels; int width = 255; int height = 255; int size = width * height; FILE *fin, *fout; if(argc != 3){ printf("Usage : %s input outpu \n", argv[0]); exit(1); } fin = fopen(argv[1], "rb"); fgets(tmp, 255, fin); if(tmp[0] != 'P'){ return 0; } sscanf(tmp, "P%d", &Magic); if(Magic < 1 || Magic > 6){ return 0; } do{ fgets(tmp, 255, fin); } while(tmp[0] == '#'); sscanf(tmp, "%d %d", &x, &y); if(x < 1 || y < 1){ return 0; } fgets(tmp, 255, fin); sscanf(tmp, "%d", &level); printf("P%d\n", &Magic); printf("%d %d\n", x, y); printf("%d\n", level); in = (unsigned char *)malloc(sizeof(unsigned char) *x*y); fread(in, sizeof(unsigned char), x*y, fin); pixels = (RGB**)malloc(width*sizeof(RGB*)); pixels[0] = (RGB* )malloc(size * sizeof(RGB)); for(i = 1; i < width; i++){ pixels[i] = pixels[i - 1] + height; } free(pixels[0]); for(i = 1; i < width * height * 3; i++){ out[i] = pixels[i][0].r * 0.299 + pixels[i][1].g * 0.587 + pixels[i][2].b * 0.114; } fout = fopen(argv[2], "wb"); fprintf(fout,"P%d\n",Magic); fprintf(fout,"# My new PGM\n"); fprintf(fout,"%d %d\n",x, y); fprintf(fout,"%d\n",level); fwrite(out, sizeof(unsigned char),x*y, fout); free(pixels); free(in); free(out); free(fin); free(fout); }

  • 「?」と「:」の意味。

    アプレットを勉強している初心者です。 javaのコードの中で「?」や「:」というのはどういった意味なのでしょうか?「?」などは検索でも無視されるらしく(?)解説されてそうなページが出てきません。 今私が勉強として読んでいるコードは下記のサイトの下から3番目の「ラインアートjavaアプレット」です。 一応使い方としては kr[i][k] = (kr[i][k]>MZ)?kr[i][k]-MX:0 という風に使っているようです。(krはintの配列。i、kはカウンターの変数。MZは28です。 よろしくお願いします。 http://hp.vector.co.jp/authors/VA012735/applet/applets.htm

    • ベストアンサー
    • Java
  • JAVAで配列の要素に、負の値が入力されたらに再入力させたいです

    JAVAで多次元配列の要素に、負の値が入力されたらに再入力させたいです int[][] a = new int[10][10]; ↑このような配列を扱うので、以下のような変数にたいしてfor文を使ったシンプルな方法は使い勝手が悪いです。 何か良い方法はありませんか? ------------------------------------------------------------------- int x = 0; for (int i = x; x <= 0;) { System.out.println("番号 : "); x = stdIn.nextInt(); }

専門家に質問してみよう