1

I'm making a program in Java that takes a grayscale image and assigns a random color to it, but I can't seem to find a way to make it work. I've looked at a couple of pages I found on the subject (this page and this page), but I can't really understand how those work.

Ideally, I want a grayscale image like this:

grayscale

to turn into this:

colored

I've tried using a hue changer, but it doesn't work on grayscale images. Everything else I've tried doesn't seem to work either.

2 Answers2

0

The way Grayscale works in RGB is that when all the values of red green and blue are equal, it is a shade of gray. (0,0,0) is black, and (255,255,255) is white. Something like (127,127,127) would be an in-between shade of gray. The higher the numbers, the lighter the gray, so (55,55,55) is darker than (190,190,190)

If you wanted to tint a grayscale image red, for example, you could create a function which increases the red value of each pixel by an amount which is randomly generated. I would go about this by using nested for loops to read each pixel of the image and add some red to it. you could also subtract the other values slightly so the image does not get too light.

Here is a pseudo-code method that you could use to achieve this:

int randRed = rand.nextInt(50)
Color[][] colorArray = new Color[image width][image height];

//nested for loops to assign each pixel into Color[][] array
for (int i=0; i < [image width]; i++) {
    for (int j=0; j < [image height]; j++) {
        colorArray[i][j] = image.getRGB();
    }
}

//nested for loops to add 'randRed' to each pixel into Color[][] array
for (int i=0; i < [image width]; i++) {
    for (int j=0; j < [image height]; j++) {
        colorArray[i][j] = new Color(image.getR()+randRed, image.getG(), image.getB());
    }
}

You would need to add checks to ensure that your rib values do not exceed 255 or go below 0, which could be achieved with some if statements. Also create functions like getR() to get the red value, etc. which shouldn't be too difficult. And figure out how to print the image back, but this should give you a good start!

CodingNinja
  • 245
  • 1
  • 12
0

Miguel’s answer on the question to which you’ve linked provides the solution, albeit not directly as Java code:

  • Convert the grayscale value of each pixel in the original image into a brightness value in an HSB color for corresponding pixel in the converted image.
  • Keep the hue of each HSB color the same at all times; that’s the color you want to apply.
  • I found setting the saturation to 100% looked good, but you are free to try other saturation values.
public static void colorize(BufferedImage image,
                            float hue) {

    Objects.requireNonNull(image, "Image cannot be null.");

    if (hue < 0 || hue > 1 || Float.isNaN(hue)) {
        throw new IllegalArgumentException(
            "Hue must be between 0 and 1 inclusive.");
    }

    int width = image.getWidth();
    int height = image.getHeight();

    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            int argb = image.getRGB(x, y);

            int alpha = (argb & 0xff000000);
            int grayLevel = (argb >> 8) & 0xff;

            float brightness = grayLevel / 255f;
            int rgb = Color.HSBtoRGB(hue, 1, brightness);

            argb = (rgb & 0x00ffffff) | alpha;
            image.setRGB(x, y, argb);
        }
    }
}
VGR
  • 40,506
  • 4
  • 48
  • 63
  • I think this looks like a good solution, but it assumes the input is already in (A)RGB "true color", and the OP states *"I've tried using a hue changer, but it doesn't work on grayscale images"*... Creating a new image for the output instead of changing the image in place will easily fix this. – Harald K Feb 23 '23 at 09:38
  • I added a main method to the program, as well as a file output to see if the program worked. However, the output file is a blank image. Here's my whole file: [link](https://pastebin.com/BCZmiYTj) – Joseph Parente Feb 23 '23 at 16:14
  • 1
    @JosephParente `new BufferedImage` creates a blank image, which is what you’re writing to a file. My code modifies the image in place. It doesn’t have to work that way, of course; you could easily modify it to call `setRGB` on a different image. – VGR Feb 23 '23 at 19:13
  • @VGR I was able to modify the code to make it work (I didn't set up the BufferedImage correctly), and it now works perfectly. Thank you for your help! Here is the final code should anyone else need it. [link](https://pastebin.com/asMtPeX) – Joseph Parente Feb 24 '23 at 13:31