tenacious
tenacious

Reputation: 91

Converting RGB pixels to greyscale makes dark pixels appear bluish

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:

enter image description here

enter image description here

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

Answers (3)

OldCurmudgeon
OldCurmudgeon

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.

A sample from your image showing blues and a little green

To fix it, roll the numbers in properly.

image.setRGB(x, y, new Color(gr,gr,gr).getRGB());

Upvotes: 2

Thallius
Thallius

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

Narayanaswamy
Narayanaswamy

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

Related Questions