4

unsigned int として5 つの色がフォーマットに保存されており、#AARRGGBB5 つすべての平均を取る必要があります。明らかに、単純に各 int を 5 で割り、それらを加算することはできません。これまでに考えた唯一の方法は、それらをビットマスクし、各チャネルを個別に実行し、それらを再度 OR で結合することです。5つすべてを平均化する巧妙で簡潔な方法はありますか?

4

4 に答える 4

1

私はあなたの問題のスマートな解決策を見つけました.悲しいことに、それは色の数が2のべき乗である場合にのみ適用されます.2色の場合に示します:

mask = 01010101

pom = ~(a^b & mask) # ^ means xor here, ~ negation

a = a & pom
b = b & pom

avg = (a+b) >> 1

この方法の秘訣は、平均を数える場合、合計のLSB (2 つの数値の場合) は除算で削除されるため、意味がありません (もちろん、ここでは整数について話しています)。あなたの問題では、部分合計のLSBは同時に隣接する色の合計のキャリービットです。すべての色の合計のLSBが であることを条件0に、これら 2 つの整数を安全に加算できます — 加算は互いに干渉しません。ビット シフトは、すべての色を 2 で割ります。

このメソッドは 4 色でも使用できますが、すべての色の最後の 2 ビットで構成される数値の合計のキャリー フラグを見つける実装を実装する必要があります。この部分を省略して、すべての色の最後の 2 ビットだけをゼロにすることもできます。この省略による最大の間違いは、すべてのコンポーネントで 1 になることです。

于 2009-07-23T11:58:31.620 に答える
0

編集この試みは後世に残しますが、それは正しくなく、機能しないことに注意してください。

コンポーネント間にゼロを挿入し、unsigned long に解析し、数値を平均化し、16 進文字列に変換し、ゼロを削除し、最後に unsigned int に解析するという「賢い」方法があります。

つまり、#AARRGGBB を #AA00RR00GG00BB に変換します。

この方法には解析と文字列操作が含まれるため、提案した方法よりも間違いなく遅くなります。

独自のソリューションを慎重に因数分解すると、実際には非常に巧妙に見えるかもしれません。

于 2009-07-22T13:32:14.517 に答える