ピクセルでRGB取得について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
nn

ピクセルでRGB取得について

#1

投稿記事 by nn » 16年前

Javaでピクセルグラバーからピクセルを取得し、
R、G、Bそれぞれの値を入手しようと思ってググってみたところ、
ソースコードで以下のような記述を見つけました。
int pixel=new int[img.getWidth(this)*img.getHeight(this)]
pixel=(int[/url])pg.getPixels();
int[/url] R=new int[256];
for(int i=0;i<pixel.length;i++){
	R[pixel>>16 & 0xff]++;
}


ここで質問なのですが、

R[pixel>>16 & 0xff]++;

の文についてなのですが、
R要素は16~32ビットの間にあるのでいらない0~16ビット分を右にシフトするのは
わかるのですが、 & 0xffは何の処理をしているのでしょうか?
他にも | 0 といったソースを見かけたのですがこちらも何を
しているのでしょうか?

ねこ

Re:ピクセルでRGB取得について

#2

投稿記事 by ねこ » 16年前

使った事があるわけじゃないので推測になりますが

getPixels関数で戻ってくるのはRGB値に透明度を加えた0xFFFFFFFF( 透明度・赤・緑・青 )の形式なんじゃないでしょうか。
R(赤)は17~24ビットになるので、16ビットシフトした値に0xFFを&演算する事で17~24ビットだけを取得します。

< | 0
0のOR演算は何も起こらない・・・と思うのでちょっと分からないですね。
何かお約束的な処理なのかもしれません。

御津凪

Re:ピクセルでRGB取得について

#3

投稿記事 by 御津凪 » 16年前

> R[pixel>>16 & 0xff]++;

& 0xff の意味は、 pixel>>16 だけでは 0x00 ~ 0xff の範囲ではない(0x0000 ~ 0xffffの範囲の)ため、
0x00 ~ 0xff の範囲にするためにマスク処理(& 0xff)を行っています。

32bit カラーでの各色成分は 256 段階で持っているため、ある色成分を取得するには、
ねこさんのような計算で取得する必要があります。


> | 0

は、見やすさなど、実際の処理には影響しないものの、明示的な意味合いを含ませるために記述することがあります。
例えば、
int color = 
    (0x80 << 24) | // 透明度(A)
    (0xFF << 16) | // 赤(R)
    (0x00 <<  8) | // 緑(G)
    (0x00 <<  0);  // 青(B)

この color の計算結果は 0x80FF0000 となり、上記のほうが比較的見やすい(かも)ですが、
(0x00 << 0) のように処理としてはまったく意味(効果)のない箇所もあります。
しかし、見やすさとしてはあったほうが見やすいと思いますがどうでしょう?


ちなみに、" | 0" と書かれている箇所はどういった処理なのでしょうか?
もしフラグ関係なら、「何も(追加)指定しない」などの意味合いを示しているかと思います。

nn

Re:ピクセルでRGB取得について

#4

投稿記事 by nn » 16年前

マスク処理なんですね。
マスク処理というと2進しかイメージなかったのでピンときませんでした。
| 0 の処理なんですが、
PixelGrabber pg = new PixelGrabber(im,0,0,w,h,pixels,0,w);
R = pixels & 0x00ff0000;
Rim = 0xff000000 |R|0|0;


の最後の行です。2回 | 0 をしているのですが何をしているのかさっぱりです。
それとふと疑問に思ったのですが、

pixel>>16
を行うと
0xffffのようにアルファ値とR要素が残ると思うのですが、
これに & 0xffのようにマスク処理をして、桁数があってないので
R要素だけちゃんとかえって来るのかな?と疑問に思ったのですが
これはどうなんでしょう?

御津凪

Re:ピクセルでRGB取得について

#5

投稿記事 by 御津凪 » 16年前

> Rim = 0xff000000 |R|0|0;

この処理は Rim へ色情報を格納しているものです。
or でそれぞれの値を結合していますが、 | で区切った場合、
A(0xff000000) | R(R) | G(0) | B(0)

と、各色要素に分けて表現していることがわかります。


ここでは、 G と B は指定していない(ゼロ)ので省略してもかまわないのですが、
ここでは省略せず "| 0 | 0" と表記しているのでしょう。


また、ここで扱っているカラー情報は、以下のような構成になっています。
・A - 25 ~ 32 ビットに格納(マスク値は 0xff000000)
・R - 17 ~ 24 ビットに格納(マスク値は 0x00ff0000)
・G -  9 ~ 16 ビットに格納(マスク値は 0x0000ff00)
・B -  1 ~  8 ビットに格納(マスク値は 0x000000ff)

さらに、各要素値を 0 ~ 255 の範囲にするためには、( color はカラー値が入っている変数)
・A -> "(color >> 24) & 0xff"
・R -> "(color >> 16) & 0xff"
・G -> "(color >>  8) & 0xff"
・B -> "(color >>  0) & 0xff" (省略して "color & 0xff" でも可)

となります。
(元の位置に戻すには左シフトに切り替えるだけです)

> pixel>>16 & 0xff

というのは、 R 要素を取り出す処理なので、この記述で問題はありません。
(カッコをつけて優先順位を明確にしたほうが良いですが)

ねこ

Re:ピクセルでRGB取得について

#6

投稿記事 by ねこ » 16年前

<Rim = 0xff000000 |R|0|0;
それはこういう事ですね。「透明度 | 赤 | 緑 | 青」
緑と青を明示してるだけで計算上では意味はないです。

<これに & 0xffのようにマスク処理をして、桁数があってないので
10進数でも10をわざわざ0010とか書かないですよね?
それと同じでマスクも省略しているだけで、実際には0x00FFを計算してるわけです。

「かえってくる」という表現をしていますが、
AND演算やOR演算はただの演算処理なので特殊な処理ってわけじゃないですよ。
2進数のマスク処理と一緒で16進数に置き換えてるだけです。

nn

Re:ピクセルでRGB取得について

#7

投稿記事 by nn » 16年前

見やすくしているだけなんですね。
詳しい回答をどうもありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る