【问题标题】:How do I perform bitwise operations properly [duplicate]如何正确执行按位运算[重复]
【发布时间】:2013-06-11 15:56:02
【问题描述】:

我的每个像素的结构如下:

...........PIXEL............
[red | green | blue | alpha]
<-8--><--8---><--8--><--8-->  

我需要执行以下操作:
1. 提取 RGBA 值
2. 对 RGB 值和 A 值进行一些计算。
3. 将它们重新组合在一起以形成具有新值的像素。

这是我的做法:

for(int i = 0;i < img.pixels.length;i++){
  int pixel = img.pixels[i];

  int red = (pixel & 0xFF000000) >>> 24;
  int green = (pixel & 0x00FF0000) >>> 16;
  int blue = (pixel & 0x0000FF00) >>> 8;
  int alpha = (pixel & 0x000000FF);

  println("Red: " + red + " Green: " + green + " Blue: " + blue + " Alpha: " + alpha);

  /*
   * Luminosity Method.
   */
  red = (int) (red * 0.21);
  green = (int) (green * 0.71);
  blue = (int) (blue * 0.07);

  /*
   * Assemble them back again
   */
  red = red << 24;
  green = green << 16;
  blue = blue << 8;

  println("AvgRed : " + red + " AvgGreen: " + green + " AvgBlue: " + blue);
  pixel= red | green | blue | alpha;

  img.pixels[i] = pixel;
 }
 updatePixels(); 

但是我再次转移他们的位置来组装他们似乎有问题。
我在控制台中有如下值:

Red: 255 Green: 83 Blue: 100 Alpha: 82 // actual values
AvgRed : 889192448 AvgGreen: 3801088 AvgBlue: 1792 // new values after calculation and shifting

这表明有问题。

我如何正确地将它们组装回来?

【问题讨论】:

  • @BrianRoach 像素是 RGBA 形式还是 ARGB?
  • 我认为是 ARGB,但它并没有改变问题。
  • @LittleChild - 这有关系吗?比特就是比特;那里的答案解释了如何将它们移入和移出。
  • @BrianRoach 是的,我需要更改 RGB 通道而不是 Alpha 通道。

标签: java processing bitwise-operators


【解决方案1】:

Color 类对这类操作非常有帮助,它有许多构造函数 - 一个获取颜色的字节码,然后可以轻松地从中获取 r、g、b 值,一旦你分离了值,你可以使用其他构造函数将其重新构建为颜色或字节码。
例如:

import java.awt.Color;

public class ColourTest {

    public static void main(String[] args) {
        Color   usingfloats = new Color(1f,0f,1f),
                preset = Color.cyan,
                usingbytecode = new Color(-16711681);

            int
            red = preset.getRed(),
            green = preset.getGreen(),
            blue = preset.getBlue();

            Color usingints = new Color(red, green, blue);
            System.out.println(usingints.getRGB());
        }
}

【讨论】:

  • 是的,抱歉,已更正。第一次回答所以我着急了。我喜欢分享简单。
  • 相当不错的类,但是如果有 alpha 通道,它如何处理呢?
  • Color 类包含所有需要的方法,例如 getAlpha(),它返回颜色的 alpha 通道的 int (0-255)。至于构造函数本身,它还有一个版本有 4 个浮点数,一个也有 4 个整数,这将有助于颜​​色的 alpha,如您所见 - 它是可选的,否则默认为 0。
【解决方案2】:

让您的生活更轻松;使用ByteBuffer:

// Byte order of a ByteBuffer is MSB by default, ie big endian
// change with the .order() method
final ByteBuffer buf = ByteBuffer.allocate(4); // size of an int

// put an integer; order of bytes dependent on buffer byte order!
buf.putInt(pixel);
buf.rewind();

// get three bytes in succession (autocast to int here)
int red = buf.get();
int green = buf.get();
int blue = buf.get();
buf.rewind();

// do calculations on red, green, blue

// put the modified bytes again; put methods all return "this"
buf.put((byte) (red & 0xff))
    .put((byte) (green & 0xff))
    .put((byte) (blue & 0xff));
    .rewind();

// use buf.getInt() to get back the modified int

请注意,您可以在for 循环之外分配缓冲区;在这种情况下,在您 .getInt() 转换后的像素之后对其执行 .rewind()

【讨论】:

    【解决方案3】:

    你做得对,只是打印在错误的地方。

    想象一下 0x05 00 00 00 的 RGBA

    您成功将R 提取为 5 并将其打印为第一个值

    然后乘以 0.21 并存储为 int (1)

    然后你 SHIFT AGAIN,红色变成 0x01 00 00 00

    您打印的是后一个值,而不是您期望的 1。

    这就是为什么 R 值变化较大而 B 较小的原因。将它们中的每一个除以 256^n(位置),您就会找到您期望的值。

    【讨论】:

    • 是的,我 OR 它与其他 3 个值一起获得一个新像素。基本上,我正在尝试使图片成为灰度。
    • 请计算1792/2563801088/256^2,看看我在说什么。
    • 答案是 30 和 56。你的意思是我应该直接划分而不是移动、提取等
    • 好的,我明白了。但是,在重新排列时,我没有得到灰度图像。相反,我得到一些有色图像。想看吗?
    • 我敢打赌,正确的格式是 ARGB 而不是 RGBA
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-06
    • 2013-05-01
    • 1970-01-01
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多