2010-12-16 19 views
1

这是关于从像素值中提取RGB的。以下是代码片段:C#WriteableBitmapEx像素预乘移位

 Byte a = (Byte)(myColor >> 24); 
     // Prevent division by zero 
     UInt32 ai = a; 
     if (ai == 0) 
     { 
      ai = 1; 
     } 
     ai = ((255 << 8)/ai); 
     Byte bA = a; 
     Byte bR = (Byte)((((myColor >> 16) & 0xFF) * ai) >> 8); 
     Byte bG = (Byte)((((myColor >> 8) & 0xFF) * ai) >> 8); 
     Byte bB = (Byte)((((myColor & 0xFF) * ai) >> 8)); 

我明白技术上,即在水平位,和二进制是怎么回事。我特别理解'Byte b#=(Byte)((((myColor >> n)& 0xFF)'部分,我不明白的是预乘(我的意思是这里的实现,而不是理论),特别是我想了解 - 所以我的问题:

  1. 为什么255被8位右移,然后devided由阿尔法
  2. 为什么每个值乘的这一点,那么结果如何呢?向左移位8位?
+0

什么是你想在这里做阅读起来的更多信息? – 2010-12-16 13:48:51

+0

了解我的问题的代码? – descf 2010-12-16 14:48:56

回答

1

这样做是为了在使用整数除法时提高精度。使用整数运算的原因可能是fo r速度。

If MyColor = 0xAABBCCDD 
AA = 170 
BB = 187 
CC = 204 
DD = 221 

Expected values: 
bA = 170 
bR = 187 * (255/170) = 280.5 
bG = 204 * (255/170) = 306 
bB = 221 * (255/170) = 331.5 

with integer division 255/170, 255/204, 255/221 will all evaluate to 1 and premultiplication becomes ineffective. 

By using this operation ai = ((255 << 8)/ai) 
with integer division: ai = (255*256)/170 = 384 
and subsequent multiplications and shifts gives you a more accurate result. 
E.g. 
bR = 187 * 384/256 = 280 
bG = 204 * 384/256 = 306 
bB = 221 * 384/256 = 331 

话虽如此,我不相信这是一个alpha预乘的好公式。

如果你有兴趣,并且对Fixed Point Arithmetic