3

ドキュメントに示されているように、 PHP imagecolorat()関数を使用して、画像ピクセルのRGB値を取得できます。

$im = imagecreatefrompng("php.png");
$rgb = imagecolorat($im, 10, 15);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;

最後の3行はまったくわかりません。それらが正しい値を返すことは知っていますが、演算子>>&演算子がどのように連携してそうするのか理解できません。誰か説明してもらえますか?

参考までに、の場合$rgb = 9750526、RGB値はであることがわかります(148,199,254)

ご回答ありがとうございます。

4

5 に答える 5

11

&と>>は、2つの異なるビット演算子PHPのビット演算子)です。それらは値のビット表現で動作し、いくつかの有用な(そして速い!)可能性を与えてくれます。

>>右シフトです。値を右シフトすると、表現のすべてのビットが右に移動します。「11100」を持っていて、それを2桁右にシフトすると、「111」が残ります(右端でシフトオフされたビットが消えます)。>>の右側の数字は、シフトするビット数を示します。

ビット単位であり、。111000と101011として表される2つの値があり、それらをビット単位で指定すると、最終的に101000になります(両方の値の同じビットが設定されているビットは1になり、それ以外の場合は0になります)。

これで、上記のコードを理解するために必要なものが揃いました。$ rgbには、24ビット(RGBAの場合は32ビットですが、ここでは無視します)を表す整数値(値は重要ではありませんが、ビットパターンは重要です)が含まれています。値は、赤の場合は8ビット、緑の場合は8ビット、青の場合は8ビットで構成されます。ただし、これらの24ビットが一緒に何を表すかではなく、個別のR、G、およびBの値が何であるかに関心があります。

私たちの値は、色の次のビットを表します。

rrrrrrrr gggggggg bbbbbbbb 

このビットマスクを>>16でシフトすると、次のようになります。

                  rrrrrrrr

これは>>16が行うことであり、赤い色を表すビットだけが残ります。ビットを完全に下に移動したので、値は[0、255]の数値を表します。次に、&255(ここでは16進表記で0xFFと表記)を追加して、関心のある8を超える漂遊ビットを削除します。G値を取得する方法を見ると、これがどのように発生するかがわかります。 :

私たちの価値は今でも勇敢にさまざまな色を表しています。

rrrrrrrr gggggggg bbbbbbbb 

このビットマスクを>>8で8桁シフトすると、次のようになります。

         rrrrrrrr gggggggg

ちょっと待って!これは、gを表すビットだけでなく、rを表すビットでもあります。これは私たちが求めている値ではありません(gが欲しいだけなので)。前の例では、rの上にビットが設定されていなかったので幸運でしたが、今回は本当に作業を切り取ってくれました。しかし、私たちは&について知っています、そしてそれが実際にそれのものであるのを見る時が来ました。

私たちは今持っています:

         rrrrrrrr gggggggg

次に、&255(コードでは0xFF)を適用します。これは、ビット値で次のように表されます。

         00000000 11111111

&は両方のオペランドに設定されたビットのみを保持するため、最終的にはg値のみになります。

                  gggggggg

シフトされた値で赤を表すビットは0になり、元の色の緑を表すビットだけが残ります。それらは[0、255]を表す同じ8ビットにシフトされているので、私たちは再び私たちの価値を手に入れました。

最後の値は、[0、255]を表すビット内で、必要な場所にすでに配置されているため、簡単です。ここで&操作を実行して、反対側に出ることができます。

rrrrrrrr gggggggg bbbbbbbb & 
00000000 00000000 11111111

最終的には:

                  bbbbbbbb

そして、私たちにも青い価値があります。

それがそれを説明することを願っています!

于 2012-07-19T22:56:10.670 に答える
1

やってみよう:

$rgb = 9750526;
var_dump(sprintf('%032b', $rgb));

$ rgb =00000000100101001100011111111110//整数は32ビットまたは64ビット-b部分は最後の8ビット

3バイト目、2バイト目、1バイト目だけが必要なので、>>(シフト)するとバイナリになります

$rgb >> 16 =  string(32) "00000000000000000000000010010100" //r part is last 8 bits
$rgb >> 8 =  string(32) "00000000000000001001010011000111" //g part is last 8 bits

&0xFFは、11111111で動作するため、結果として次のようになります。

r = 10010100
g = 11000111
b = 11111110

そして私はそれらが(148,199,254)であることを願っています;)

于 2012-07-19T22:52:55.180 に答える
1

>>ビット単位の右シフトを意味するため、ビットは右にn(それぞれ16と8)の位置に移動します。

R=1バイト=8ビット

RRGGBB >> 16  =  0000RR
RRGGBB >> 8   =  00RRGG

ビット単位のAND演算&は、結果に不要な残りのものを削除するために使用されます。これは、残る必要のある部分を除いて、すべての場所でゼロのマスクを使用することによって行われます。

00RRGG & 0000FF = 0000GG 
于 2012-07-19T22:48:27.590 に答える
1

最初の出現>>16は、赤だけが残るまですべてのビットを右にシフトし、その後、&0xFFで数字の先頭を切り取っていると推測しています。その例では赤のビット深度はわかりませんが(色は3バイトの倍数になると思います)、次のようになります。

rrggbb = 125438 // input
>> 16 // shift right (might be 8 for this example)
0000rr = 000012 // result
& 0xFF // cut beginning
rr = 12

そして他の色についても同様です。

于 2012-07-19T22:40:38.997 に答える
0

imageColorAt()は、赤、緑、青の値を含む24ビットの数値を返します。赤の値は2^16で乗算され、緑の値は2 ^ 8で乗算され、青は「そのまま」残されます。

16進数では、値は0x94C7FEです。右に16ビットシフトすると、最後の4つのニブルが失われ、0x94のままになります。「&0xFF」は最後の8ビットを取ります(したがって、それは不要です)。

通常、このシフト'n'カットは次のように行われます。

$value = imageColorAt(...)   // Gets 94C7FE
$blue  = $value & 0xFF;       // Takes the last "FE" (254 in decimal)
$value >>= 8;                 // Shifts right, 94C7 remains
$green = $value & 0xFF;       // Takes "C7"
$value >>= 8;                 // Shifts right, 94 remains
$red   = $value;              // Takes "94" hex, which is 148 dec.
于 2012-07-19T22:47:21.143 に答える