skip to Main Content

I’m looking to use a very crude heightmap I’ve created in Photoshop to define a tiled isometric grid for me:

Map:
http://i.imgur.com/jKM7AgI.png

I’m aiming to loop through every pixel in the image and convert the colour of that pixel to a scale of my choosing, for example 0-100.

At the moment I’m using the following code:

    try
    {
        final File file = new File("D:\clouds.png");
        final BufferedImage image = ImageIO.read(file);

        for (int x = 0; x < image.getWidth(); x++) 
        {
            for (int y = 0; y < image.getHeight(); y++) 
            {
                int clr = image.getRGB(x, y) / 99999;
                if (clr <= 0)
                    clr = -clr;

                System.out.println(clr);        
            }
        }
    }
    catch (IOException ex)
    {
         // Deal with exception
    }

This works to an extent; the black pixel at position 0 is 167 and the white pixel at position 999 is 0. However when I insert certain pixels into the image I get slightly odd results, for example a gray pixel that’s very close to white returns over 100 when I would expect it to be in single digits.

Is there an alternate solution I could use that would yield more reliable results?

Many thanks.

2

Answers


  1. getRGB returns all channels packed into one int so you shouldn’t do arithmetic with it. Maybe use the norm of the RGB-vector instead?

    for (int x = 0; x < image.getWidth(); ++x) {
        for (int y = 0; y < image.getHeight(); ++y) {
            final int rgb = image.getRGB(x, y);
            final int red   = ((rgb & 0xFF0000) >> 16);
            final int green = ((rgb & 0x00FF00) >>  8);
            final int blue  = ((rgb & 0x0000FF) >>  0);
            // Norm of RGB vector mapped to the unit interval.
            final double intensity =
                Math.sqrt(red * red + green * green + blue * blue)
                / Math.sqrt(3 * 255 * 255);
        }
    }
    

    Note that there is also the java.awt.Color class that can be instantiated with the int returned by getRGB and provides getRed, getGreen and getBlue methods if you don’t want to do the bit manipulations yourself.

    Login or Signup to reply.
  2. Since it’s a grayscale map, the RGB parts will all be the same value (with range 0 – 255), so just take one out of the packed integer and find out what percent of 255 it is:

    int clr = (int) ((image.getRGB(x, y) & 0xFF) / 255.0 * 100);
    
    System.out.println(clr);        
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search