我有一个类Pixel,它有方法getRed,getBlue,getGreen,setRed,setBlue,setGreen(r,g,b) 到目前为止,一切都是单独的,但当我把它放在一起setGreen和setBlue不起作用。我做错了吗?
public class Pixel {
int pixel;
public Pixel (int pixel) {
this.pixel = pixel;
}
public int getRed() {
int red = pixel >> 16;
red = red & (0xFF);
return red;
}
public int getGreen() {
int green = pixel >> 8;
green = green & (0xFF);
return green;
}
public int getBlue() {
int blue = pixel;
blue = blue & (0xFF);
return blue;
}
public void setRed(int red) {
pixel = (pixel & ~(0xFFFF0000)) << 16;
pixel= ((red << 16))|pixel ;
}
public void setGreen(int value) {
pixel = (pixel & ~(0xFF00FF00)) << 8;
pixel= (value << 8) |pixel;
}
public void setBlue(int value) {
pixel = (pixel & ~(0xFFFFFF00));
pixel= (value) |pixel;
}
public static void main(String[] args) {
Pixel p3 = new Pixel(0xFF000000);
System.out.printf("rgb = (%d, %d, %d)\n", p3.getRed(), p3.getGreen(), p3.getBlue());
p3.setRed(42);
p3.setGreen(18);
p3.setBlue(225);
System.out.printf("rgb = (%d, %d, %d)\n", p3.getRed(), p3.getGreen(), p3.getBlue());
p3.setRed(-1);
p3.setGreen(500);
p3.setBlue(1000);
System.out.printf("rgb = (%d, %d, %d)\n", p3.getRed(), p3.getGreen(), p3.getBlue());
}
}
我应该得到这个结果:
rgb = (0, 0, 0)
rgb = (42, 18, 225)
rgb = (255, 244, 232)
但这就是我得到的
rgb = (0, 0, 0)
rgb = (0, 0, 225)
rgb = (0, 3, 232)
答案 0 :(得分:1)
例如考虑您的setGreen
方法:
public void setGreen(int value) {
pixel = (pixel & ~(0xFF00FF00)) << 8;
pixel = (value << 8) | pixel;
}
最初,您的pixel
为AARRGGBB
。首先,您正在将当前值GG
中的pixel
部分正确设置为0(暂时忽略alpha)。 (pixel & ~(0xFF00FF00)) == (AARRGGBB & 0x00FF00FF) == 00RR00BB
。但是,接下来您将该值向左移动8位,因此您得到RR00BB00
。接下来,您(正确地)左移您获得的绿色值作为参数。你会得到(000000GG << 8) == 0000GG00
。最后,你正在使用之前的值:(RR00BB00 | 0000GG00) == RR00XX00
其中X
es是一些垃圾,它们起源于或者将旧的蓝色与新的绿色位组合在一起。你能看到要解决的问题吗?
setBlue
方法还有另一个问题。 (pixel & ~(0xFFFFFF00)) == (AARRGGBB & 000000FF) == 000000BB
。将其与上面setGreen
的(正确)掩码进行比较。
最后,您的方法似乎应该优雅地处理无效值(-1,500,1000)。因此,您应该将参数的最后8位设置为0.我只是建议,因为您的所需输出似乎要求它。在编写良好的Java程序中,如果传递超出范围的值,最好抛出异常,而不是静默忽略无效位。或者,您可以更改方法以接受byte
而不是int
。这将是最好的解决方案,因为现在通过无效的论证是完全不可能的。
将它们放在一起,以下是它的工作原理。我还对代码进行了一些修改,以便我们可以更容易地看到正在发生的事情。 0位的移位当然没用,但我出于光学原因将它们包括在内。
public final class Pixel {
private int value;
public Pixel (int rgb) {
this.value = value;
}
public int getRed() {
return (this.value >> 16) & 0xFF;
}
public int getGreen() {
return (this.value >> 8) & 0xFF;
}
public int getBlue() {
return (this.value >> 0) & 0xFF;
}
public void setRed(final int r) {
this.value = (this.value & 0xFF00FFFF) | ((r & 0xFF) << 16);
}
public void setGreen(final int g) {
this.value = (this.value & 0xFFFF00FF) | ((g & 0xFF) << 8);
}
public void setBlue(final int b) {
this.value = (this.value & 0xFFFFFF00) | ((b & 0xFF) << 0);
}
@Override
public String toString() {
return String.format("rgb = (%3d, %3d, %3d)",
this.getRed(),
this.getGreen(),
this.getBlue());
}
public static void main(String[] args) {
final Pixel pixel = new Pixel(0);
System.out.println(pixel);
pixel.setRed(42);
pixel.setGreen(18);
pixel.setBlue(225);
System.out.println(pixel);
pixel.setRed(-1);
pixel.setGreen(500);
pixel.setBlue(1000);
System.out.println(pixel);
}
}
运行上述程序的输出:
rgb = ( 0, 0, 0)
rgb = ( 42, 18, 225)
rgb = (255, 244, 232)