0

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

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

这表明出了点问题。

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

4

3 回答 3

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());
        }
}
于 2013-06-14T22:24:13.593 回答
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()转换像素之后执行它。

于 2013-06-14T22:19:41.823 回答
0

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

想象一下 0x05 00 00 00 的 RGBA

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

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

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

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

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

于 2013-06-14T22:16:57.027 回答