Search code examples
javaimage-processingcolor-space

Color.HSBtoRGB is not keeping changes made into HSB color space


I'm loading a BufferedImage and I've switched to HSB color space to to some color correction, then I'm going back to RGB color space to display the results but seems that the cjanges made into HSB color space are not having effect. Here's my code:

import java.awt.Color;
import java.awt.image.BufferedImage;

public class ImageOperations {

    public static BufferedImage Threshold(BufferedImage img,int requiredThresholdValue) {

        int height = img.getHeight();
        int width = img.getWidth();
        BufferedImage finalThresholdImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB) ;

        int red = 0;
        int green = 0;
        int blue = 0;

        float hue = 0;
        float sat = 0;
        float bri = 0;

        int r = 0;
        int b = 0;
        int g = 0;



        for (int x = 0; x < width; x++) {
//          System.out.println("Row: " + x);
            try {

                for (int y = 0; y < height; y++) {

                    //Get RGB values of pixels
                    int color = img.getRGB(x, y);   
                    red = ImageOperations.getRed(color);
                    green = ImageOperations.getGreen(color);
                    blue = ImageOperations.getBlue(color);

                    //Convert to HSV color space
                    float[] hsb = new float[3];
                    Color.RGBtoHSB((color>>16)&0xff, (color>>8)&0xff, color&0xff, hsb);
                    hue = hsb[0];
                    sat = hsb[1];
                    bri = hsb[2];

                    //apply changes based on threshold value
                    if ((hue+sat+bri)/3 < (int) (requiredThresholdValue)){
                        sat = sat -(50);
                        bri = bri +100;

                        int rgb = Color.HSBtoRGB(hsb[0], hsb[1], hsb[2]);
                        r = ImageOperations.getRed(rgb);
                        g = ImageOperations.getGreen(rgb);
                        b = ImageOperations.getBlue(rgb);
                        finalThresholdImage.setRGB(x,y,ImageOperations.mixColor(r,g,b));
                    }
                    else {
                        finalThresholdImage.setRGB(x,y,ImageOperations.mixColor(255, 255,255));
                    }


                }
            } catch (Exception e) {
                 e.getMessage();
            }
        }

        return finalThresholdImage;
    }

    private static int mixColor(int r, int g, int b) {
        return r<<16|g<<8|b;
    }

    public static int getRed(int rgb) {
        return (rgb & 0x00ff0000)  >> 16;
    }

    public static int getGreen(int rgb) {
        return  (rgb & 0x0000ff00)  >> 8;
    }

    public static int getBlue(int rgb) {
        return (rgb & 0x000000ff)  >> 0;

    }

}

I'm using eclipse and it doesn't give any errors, there's probably a semantic error, but I can't figure it out.


Solution

  • First you do:

    sat = hsb[1];
    

    Then:

    sat = sat -(50);
    

    Then:

    int rgb = Color.HSBtoRGB(hsb[0], hsb[1], hsb[2]);
    

    It's almost as if you expect hsb[1] to be updated when you update sat? In conclusion, do:

    int rgb = Color.HSBtoRGB(hue, sat, bri);