Nik*_*lle 4 bit-manipulation colors go bitmapdata rgba
所以我一直在筛选Go标准库中的一些代码,试图理解他们的图像和颜色包,但发现了一些我无法理解的代码.来自http://golang.org/src/pkg/image/color/color.go?s=794:834#L14
根据我的理解,它应该将8位预先alpha乘法的RGB值转换为16位的值,保存在32位变量中,以防止它们在图像关节成像中相乘时溢出.
我无法理解的是像r |= r << 8我理解的线条这相当于r = r*2^8+r因为r << 8在右边插入零并且它们与旧的r相关.
对于r = 255的输入,这评估为65535 = 2 ^ 16 - 1这是预期的,但对于中间的值没有意义,这些值实际上没有映射到更大范围内的比例.例如,127 get被映射到32639,而我期望32767代表127.我错过了什么?我认为它与pre-alpha-multiplication有关...
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
}
Run Code Online (Sandbox Code Playgroud)
pax*_*blo 10
不,你所看到的实际上是有道理的.
可以考虑单个(例如红色)值.它决定了像素中的红色量,并且作为一个8位数量,它介于0到255之间.因此,您可以表示该范围内的所有红色值.
如果您只是将其移位8位(或乘以256)以获得16位颜色值,那么最终会得到256的倍数,介于0和255*256(65280)之间.
虽然这可以相对较好地扩大红色,但它并不能在整个16位范围内正确分布.
例如,8位范围内的255表示最大红度.简单地将其乘以256并不会给出16位刻度上的最大红色,即65535.
通过乘以256 然后加上原始值(实际乘以257),它可以在0..65535范围内正确分布.
这与将单位数整数0..9扩展到范围内相同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
Run Code Online (Sandbox Code Playgroud)