2012-05-09 4 views
4

私はGo標準ライブラリの画像と色のパッケージを理解しようとしていますが、いくつかのコードを見つけようとしています。 。 http://golang.org/src/pkg/image/color/color.go?s=794:834#L14Go標準ライブラリのいくつかのビットマジックの意味を作る

私の理解では、8ビットのアルファ乗算RGB値を16ビットのものに変換し、32ビット変数に保存して、画像の関節炎を乗り越える際にオーバーフローするのを防ぐ必要があります。私はr << 8右にゼロを挿入し、それらが古いR OR操作を取得するので、これはr = r*2^8+rと同等であることを理解として私が意味することはできませんどのような

r |= r << 8のような線です。

r = 255の入力に対しては、これは期待どおりの65535 = 2^16-1と評価されますが、中間の値は実際には何かに比例してマッピングされませんより広い範囲で。 たとえば、127のgetは32639にマッピングされますが、私は32767が127を表すことを期待しています。 何が欠けていますか?私はそれがプレアルファ乗算と関係があると思います...

func (c RGBA) RGBA() (r, g, b, a uint32) { 
    r = uint32(c.R) 
    r |= r << 8 
    g = uint32(c.G) 
    g |= g << 8 
    b = uint32(c.B) 
    b |= b << 8 
    a = uint32(c.A) 
    a |= a << 8 
    return 
} 

答えて

10

いいえ、あなたが実際に見ているものはありません。

単一の(赤い値など)値を考えてください。それはピクセルの赤みの量を指示し、8ビットの量として0から255の間のどこかにあるので、範囲内の赤みの値をすべて表すことができます。

16ビットのカラー値を得るためにビットシフトした場合(または256を掛けた場合)は、0〜255 * 256(65280)の間の256の倍数になります。

赤の度合いは比較的よくスケールされますが、完全に16ビットの範囲で適切に分散されるわけではありません。

たとえば、8ビットの範囲の255は最大の赤みを意味します。単純にそれは、256では(事実上257で乗算)の元を追加し、その後256及びを乗じて65535

だろう16ビットのスケールであなたに赤みの最大量を与えていないことを掛けます0..65535の範囲で正しく分配されます。

0..9の1桁の整数を0..99に拡大することと同じです。 10で乗算する一つの方法ですが、良い方法は10で乗算し、元の値を追加します(または11で乗算)することです:

n  n*10  n*10+n 
-  ----  ------ 
0  0   0 
1  10   11 
2  20   22 
3  30   33 
4  40   44 
5  50   55 
6  60   66 
7  70   77 
8  80   88 
9  90   99 
+0

私はそれだけシフトし、その後、より良いのですが、それはまだ間違っていないことを理解できますか? 例えば、小数点の場合、5 getは55にマップされるので、真ん中にあるという性質を失います。 –

+2

@NiklasSchnelle、トップ値が10(または9.9999 ...)であると考えると、5は真ん中にあります。実際には、トップ値は9なので、4.5が「中間」値になります。したがって、5が存在する「位置」は5/9であり、0.99の範囲(55/99)に55が存在するのとまったく同じ場所です。あなたの問題は、バイト範囲が '[0,256]'(ゼロを含み256を除いて、255.99までを意味する)だと考えているようです。実際は '[0,255]'です。両端)。 – paxdiablo

+0

つまり、「中間」は上限と下限の( '0 + 9)/ 2 = 4.5'の平均です。 4.5倍の11倍にすると49.5倍になります。これは '(0 + 99)/ 2 = 49.5'という2桁の範囲で同じプロパティを持ちます。 – paxdiablo