4

そのため、Go標準ライブラリのコードをふるいにかけて、イメージとカラーパッケージを理解しようとしましたが、理解できないコードがいくつか見つかりました。http://golang.org/src/pkg/image/color/color.go?s=794:834#L14から

私の理解では、8ビットの事前にアルファ乗算されたRGB値を16ビットの値に変換し、32ビット変数に保存して、画像のアーティメティックで乗算するときにオーバーフローしないようにする必要があります。

私が理解できないのは、r |= r << 8私が理解しているような行です。これは、 が右側にゼロを挿入し、古い r と or'ed を取得するためですr = r*2^8+rr << 8

r=255 の入力の場合、これは 65535=2^16 - 1 と評価されますが、これは予想どおりですが、より大きな範囲で比例するものに実際にマップされない中央の値には意味がありません. たとえば、127 は 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
}
4

1 に答える 1

10

いいえ、あなたが見ているものは実際には理にかなっています。

単一の値 (たとえば、赤) を考えます。これは、ピクセルの赤みの量を決定し、8 ビットの量として、0 から 255 の間のどこかにあります。したがって、範囲内の赤みのすべての値を表すことができます。

それを 8 ビットだけビットシフト (または 256 倍) して 16 ビットのカラー値を取得すると、0 から 255*256 (65280) までの範囲の 256 の倍数になります。

これにより、赤みが比較的うまく拡大されますが、16 ビットの範囲全体に適切に分散されません。

たとえば、8 ビット範囲の 255 は、最大の赤みを意味します。単純に 256 を掛けただけでは、16 ビット スケールでの赤みの最大量 (65535) は得られません。

256 を掛けてから元の値加算すると (事実上 257 を掛けます)、0..65535 の範囲に正しく分散されます。

0..91 桁の整数を range にスケールアップするのと同じです0..99。10 を掛けるのは 1 つの方法ですが、より良い方法は、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
于 2012-05-09T08:03:41.233 に答える