I have a class Pixel that has methods getRed, getBlue, getGreen, setRed, setBlue, setGreen (r,g,b) and so far everything works individually but when i put it TOGETHER setGreen and setBlue don't work. Am I doing something wrong with the masking?
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());
}
}
I should be getting this as my result:
rgb = (0, 0, 0)
rgb = (42, 18, 225)
rgb = (255, 244, 232)
but this is what im getting
rgb = (0, 0, 0)
rgb = (0, 0, 225)
rgb = (0, 3, 232)
Consider for example your setGreen
method:
public void setGreen(int value) {
pixel = (pixel & ~(0xFF00FF00)) << 8;
pixel = (value << 8) | pixel;
}
Initially, your pixel
is AARRGGBB
. First, you are setting the GG
part in the current value of pixel
to 0 correctly (ignoring alpha for now). (pixel & ~(0xFF00FF00)) == (AARRGGBB & 0x00FF00FF) == 00RR00BB
. However, next you shift that value 8 bits to the left, so you get RR00BB00
. Next, you are (correctly) left-shifting the green value you got as a parameter. You'll get (000000GG << 8) == 0000GG00
. And finally, you are or'ing that with the value from before: (RR00BB00 | 0000GG00) == RR00XX00
where the X
es are some garbage that originate from or'ing together the old blue with the new green bits. Can you see what to fix?
There is another issue in the setBlue
method. (pixel & ~(0xFFFFFF00)) == (AARRGGBB & 000000FF) == 000000BB
. Compare that with the (correct) mask for setGreen
above.
Finally, your methods seem to be supposed to handle invalid values (–1, 500, 1000) gracefully. So you should set all but the last 8 bits of your arguments to 0. I'm only suggesting that because your required output seems to ask for that. In a well-written Java program, it would b better to throw an exception if out-of-range values are passed, rather than silently ignoring the invalid bits. Alternatively, you could change your methods to accept a byte
instead of an int
. This would be the best solution since now it would be outright impossible to pass an invalid argument.
Putting this together, here is how it could work. I have also polished the code a little so we can hopefully see more easily what is going on. The shifts by 0 bits are of course useless but I include them for optical reasons.
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);
}
}
Output of running the above program:
rgb = ( 0, 0, 0)
rgb = ( 42, 18, 225)
rgb = (255, 244, 232)