C#中的>>运算符是什么?

10

我对C#很新,正在尝试做一个基本的图像处理软件。我理解这个片段从WriteableBitmap像素"current"的ARGB整数值中提取了A、R、G和B。

for(int i = 0; i < bitmapArray.Length; i++) {
    var current = bitmapArray[i];

    var alpha = (byte)(current >> 24);
    var red = (byte)(current >> 16);
    var green = (byte)(current >> 8);
    var blue = (byte)(current);
    //Some code
 }
" >> "是用来对值进行转换的吗?
另外,如果我针对r、g和b分别进行计算,该如何将它们转换回整数ARGB值以替换原始像素为新像素?
提前感谢。
编辑:谢谢大家,现在我懂了。

实际上,Silverlight中的Color结构没有提供将Int32转换为Color的方法,这真的很令人恼火。 - AnthonyWJones
3个回答

16

这是一个二进制移位运算符。

如果你有一个由(a,r,g,b)定义的颜色,它的二进制表示将会像这样(假设通道深度为8位):

AAAAAAAA RRRRRRRR GGGGGGGG BBBBBBBB

所以,将整个东西向左平移24个位置,你就得到了alpha通道

AAAAAAAA

将值左移16位即可获取alpha通道和红色通道。

AAAAAAAARRRRRRRR

现在,由于它被转换为字节,只有前8位被提取出来

(byte)AAAAAAAARRRRRRRR == RRRRRRRR

你可以通过将颜色值向右移动16位,然后与11111111(0xFF)相与来获取红色通道。

AAAAAAAARRRRRRRR &
0000000011111111
----------------
00000000RRRRRRRR

1
+1. 这是一个很好的解释,我一直想知道位移是如何工作的。如果您有时间,能否给出一个示例,说明上述操作如何改变颜色值以及如何改变。比如,位移如何将128、64、256转换为其他RGB值。此外,我仍然不理解(byte)AAAAAAAARRRRRRRR == RRRRRRRR(即从右到左提取吗?),但至少我现在比访问这个答案之前更了解了。 - Todd Main
@Otaku:二进制从右往左读取,在这种情况下,“前8位”就意味着这个。 - junkforce
如果你将(pixel&0xff000000)转换为字节,无论如何都会得到零,因为最右边的8位将为0。所以我认为你的最后一个块是不正确的。 - Jacob
糟糕!你是对的。这就是我匆忙回答的后果。 - Ed S.
@Otaku:就像junkforce所说的那样,你只是裁剪了第一个8位并将其填充到一个字节中。其余部分(即,任何> 255的部分)都被丢弃了。 - Ed S.

12

这段代码将current值向右移动位。在这个特定的代码片段中,它似乎将所选位图数组元素的每个颜色信息字节提取成单独的颜色字节。

http://msdn.microsoft.com/en-us/library/xt18et0d.aspx

假设你的数组包含整数,为了将计算出的值重新赋给数组元素,你需要反转位移过程并将结果重新进行按位或(OR)操作,像下面这样:

int current = (alpha << 24) | (red << 16) | (green << 8) | blue; 

我想知道... BitConverter.GetBytes(current) 是否太复杂了?嗯,对于严肃的图像处理来说可能会太慢了。 - Joey
@Johannes: BitConverter非常快速。我想它在这里应该很合适。 - Robert Harvey
1
这是一个如此简单、明显和常见的操作,我不认为使用除了二进制运算符以外的任何东西有什么优势。如果你不理解正在发生的事情,那么你应该学习或远离图像处理(不是特指你,而是一般而言)。 - Ed S.
罗伯特:你会得到一个 byte[],你可能不想为每个像素创建一个新的;这就是我“可能太慢”的编辑背后的原理。 - Joey
1
@Ed:不会的。你只会得到一个负的32位数。虽然它是有符号的,但你仍然可以使用32位。请看LukeH在他的答案下面的评论。 - Robert Harvey
显示剩余2条评论

2

除了Robert的回答之外,为了回答你问题的第二部分,你可以使用<<(左移)|(按位或)运算符将各个组件合并回一个整数:

int combined = (alpha << 24) | (red << 16) | (green << 8) | blue;

@Robert:OP没有具体说明,我认为从哲学上讲,它只是一组4个无符号八位字节。如果存储机制是一个int,那么我的代码将可以正常工作(如果alpha值大于127,则结果将是负的int)。如果存储机制是一个uint,则需要进行一些额外的转换等操作。 - LukeH

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接