如何正确执行按位操作

时间:2013-06-14 22:09:18

标签: java processing bitwise-operators

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

...........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

表明出现了问题。

如何正确组装它们?

3 个答案:

答案 0 :(得分:2)

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());
        }
}

答案 1 :(得分:1)

让您的生活更轻松;使用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循环中分配缓冲区;在这种情况下,在.rewind()转换后的像素之后,请在.getInt()上进行{{1}}。

答案 2 :(得分:0)

你做得对,只是打印位置错误。

想象RGBA为0x05 00 00 00

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

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

然后你再次移动,红色变为0x01 00 00 00

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

这就是为什么R值更多而B更少的原因。将它们中的每一个除以256 ^ n(位置),然后找到您期望的值。