【问题标题】:What does the >> operator do in C#?C# 中的 >> 运算符有什么作用?
【发布时间】:2010-08-15 00:26:01
【问题描述】:

我对 C# 还很陌生,正在尝试做一个基本的图像处理软件。我知道这个 sn-p 从 WriteableBitmap 像素“当前”的 ARGB int 值中提取 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 的方法,这实际上非常令人恼火。

标签: c# silverlight argb


【解决方案1】:

是二元移位运算符。

如果你有一个由 (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。这是一个很好的解释,我一直想知道位移及其工作原理。如果您有时间,很高兴看到一个示例,说明上述操作如何更改颜色值以及如何更改。就像位移如何将 128、64、256 更改为其他 RGB 值一样。另外,我仍然不理解(byte)AAAAAAAARRRRRRRR == RRRRRRRR(即它是从右到左提取的吗?),但至少我比访问这个答案之前知道的更多。
  • @Otaku:二进制是从右到左读取的,在这种情况下,“前 8 位”就是这个意思。
  • 如果你将 (pixel & 0xff000000) 转换为一个字节,无论如何你都会得到一个零,因为最右边的 8 位将为 0。所以我不认为你的最后一个块是正确的。
  • 天啊!你说得对。这就是我试图回答得太快的结果。
  • @Otaku:正如 junkforce 所说,您只是裁剪前 8 位并将其填充到一个字节中。其余的(即任何大于 255 的)都被丢弃。
【解决方案2】:

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

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

假设您的数组包含整数,要将计算值返回到数组元素中,您将反转位移过程并将结果 OR 一起返回,如下所示:

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

【讨论】:

  • 我想知道...BitConverter.GetBytes(current) 是不是太复杂了?嗯,对于严重的图像处理来说可能太慢了。
  • @Johannes:BitConverter 非常快。我想这里会很合适。
  • 这是一个如此简单、明显和常见的操作,我看不到使用除二元运算符之外的任何东西的优势。如果你不明白发生了什么,你应该学习或远离图像处理(不是特别是“你”,只是笼统地说)
  • 罗伯特:你会得到一个byte[],你可能不希望每个像素都有一个新的;这就是我“可能太慢”编辑背后的理由。
  • @Ed:不,不会。你只会得到一个负的 32 位数字。虽然它是有符号数,但仍有 32 位可供使用。见 LukeH 的评论below his answer.
【解决方案3】:

进一步回答 Robert 的问题 - 并涵盖您问题的第二部分 - 您可以使用 &lt;&lt; (left-shift)| (bitwise OR) 运算符将单独的组件组合回整数:

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

【讨论】:

  • @Robert:OP 没有具体说明,我想从哲学上讲两者都不是——它只是一组 4 个无符号八位字节。如果存储机制int,那么我的代码就可以正常工作(如果alpha 值大于127,结果将是负的int)。如果存储机制是uint,则需要一些额外的转换等。
猜你喜欢
  • 2010-11-21
  • 2011-03-29
  • 2015-10-15
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多