I have following code, which creates grayscale BufferedImage and then sets random colors of each pixel.
import java.awt.image.BufferedImage;
public class Main {
public static void main(String[] args) {
BufferedImage right = new BufferedImage(100, 100, BufferedImage.TYPE_BYTE_GRAY);
int correct = 0, error = 0;
for (int i = 0; i < right.getWidth(); i++) {
for (int j = 0; j < right.getHeight(); j++) {
int average = (int) (Math.random() * 255);
int color = (0xff << 24) | (average << 16) | (average << 8) | average;
right.setRGB(i, j, color);
if(color != right.getRGB(i, j)) {
error++;
} else {
correct++;
}
}
}
System.out.println(correct + ", " + error);
}
}
In approximately 25-30% pixels occurs weird behaviour, where I set color and right afterwards it has different value than was previously set. Am I setting colors the wrong way?
Here is your solution: ban getRGB and use the Raster (faster and easier than getRGB) or even better DataBuffer (fastest but you have to handle the encoding):
In your case getRGB is terrible, because the encoding is an array of byte (8 bits), and you have to manipulate RGB values with getRGB. The raster does all the work of conversion for you.
Wild guess:
Remove (0xff << 24) | which is the alpha channel, how intransparent/opaque the color is. Given yes/no transparent and average < or >= 128 application of transparency, 25% could be the wrong color mapping (very wild guess).
I think your issue has to do with the image type (third parameter for BufferedImage constructor). If you change the type to
BufferedImage.TYPE_INT_ARGB
, then you will get 100% correct results.Looking at the documentation for
BufferedImage.getRGB(int,int)
there is some conversion when you get RGB that is not the default color spaceSo you're probably seeing the mismatches due to the conversion.