Reputation: 91
I'm currently experimenting with images in Java and was trying to convert a RGB image to greyscale using the BufferedImage class.
My idea was to get the RGB values of every pixels and set them to (R+G+B)/3:
BufferedImage image = ImageIO.read(new File(file));
int[] pixel;
int r, g, b;
for (int y = 0; y < image.getHeight(); y++)
{
for (int x = 0; x < image.getWidth(); x++)
{
pixel = image.getRaster().getPixel(x, y, new int[3]);
r = pixel[0];
g = pixel[1];
b = pixel[2];
int gr = (int)((r+g+b)/3);
String hex = Integer.toHexString(gr)+Integer.toHexString(gr)+Integer.toHexString(gr);
int i = Integer.parseInt(hex, 16);
image.setRGB(x, y, i);
}
}
ImageIO.write(image, "jpg", new File("im2.jpg"));
The result was this:
Regardless of the fact that this is probably the most inefficient way of converting an image to greyscale, I have no idea why this is happening. What am I missing here?
Upvotes: 3
Views: 423
Reputation: 65821
This happens when the hex value is not 2-digits. E.G. Integer.toHexString(10)
returns "a".
So, for example, if r = 10
and g = 10
and b = 10
you will be doing Integer.toHexString("aaa")
which is quite blue (aa
= 170
) with a tinge of green (a
= 10) and no red. This effect will clearly happen more in dark areas of the image and result in mostly blue but some greenish effect.
Here's a blowup of a small section of your image showing the blueing and slight greening.
To fix it, roll the numbers in properly.
image.setRGB(x, y, new Color(gr,gr,gr).getRGB());
Upvotes: 2
Reputation: 2619
When your grey value gets lower then 16, it will no longer be an 2 digit hex number. So your hex string will look like "444" instead of "040404". This will result in a blue color.
Why dont you use
Color myColor = new Color(gr, gr, gr);
Upvotes: 2
Reputation: 137
Instead of :
int gr = (int)((r+g+b)/3);
String hex = Integer.toHexString(gr)+Integer.toHexString(gr)+Integer.toHexString(gr);
int i = Integer.parseInt(hex, 16);
image.setRGB(x, y, i);
try this:
Color newColor = new Color(r+g+b,r+g+b,r+g+b);
image.setRGB(j,i,newColor.getRGB());
Upvotes: 1