22

I've had a look at the ColorSpace class, and found the constant TYPE_HLS (which presumably is just HSL in a different order).

Can I use this constant to create a Color from hue, saturation, and luminosity? If not, are there any Java classes for this, or do I need to write my own?

Eric
  • 95,302
  • 53
  • 242
  • 374
  • The "top" answer given below is WRONG. HSB is NOT the same as HSL. You will end up getting much darker colors than you expect. I have added a sample implementation of HLS (HSL) below. – xtempore Nov 26 '15 at 21:54

6 Answers6

14

Most of the given answers here seem to assume that HSL == HSB, which is false. The HSB colorspace is useful (and used) in many cases, but there is one notable exception: CSS. The non-RGB css color functions, hsl() and hsla() are HSL, not HSB. As such, it is very useful to be able to convert to and from HSL in java.

There is a good writeup about the problem here: http://tips4java.wordpress.com/2009/07/05/hsl-color/ TL;DR: the code is here: http://www.camick.com/java/source/HSLColor.java

I have created a gist backup, should the blog ever go down: https://gist.github.com/Yona-Appletree/0c4b58763f070ae8cdff7db583c82563

The methods therein are pretty easy to extract if you don't want to use the whole class.

License

The code appears to be in the public domain, as noted on the "About" page of the blog (https://tips4java.wordpress.com/about/):

We assume no responsibility for the code. You are free to use and/or modify and/or distribute any or all code posted on the Java Tips Weblog without restriction. A credit in the code comments would be nice, but not in any way mandatory.
Yona Appletree
  • 8,801
  • 6
  • 35
  • 52
12

EDIT: I realize HSB != HSL, the answer below is for HSB.

I don't think there is any need to use ColorSpaces here. Try something like the following:

float hue = 0.9f; //hue
float saturation = 1.0f; //saturation
float brightness = 0.8f; //brightness

Color myRGBColor = Color.getHSBColor(hue, saturation, brightness);
Justin Garrick
  • 14,767
  • 7
  • 41
  • 66
  • 7
    Note that the B is actually "brightness", not luminosity/lightness, and is another term for the "value" attribute of the HSV color space. – JAB Jun 08 '10 at 17:26
8

Here is a simple implementation that will return a Color based on hue, saturation, and lightness values from 0.0 to 1.0...

static public Color hslColor(float h, float s, float l) {
    float q, p, r, g, b;

    if (s == 0) {
        r = g = b = l; // achromatic
    } else {
        q = l < 0.5 ? (l * (1 + s)) : (l + s - l * s);
        p = 2 * l - q;
        r = hue2rgb(p, q, h + 1.0f / 3);
        g = hue2rgb(p, q, h);
        b = hue2rgb(p, q, h - 1.0f / 3);
    }
    return new Color(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255));
}

EDIT by Yona-Appletree:

I found what I think is the correct hue2rgb function and tested it as working:

private static float hue2rgb(float p, float q, float h) {
    if (h < 0) {
        h += 1;
    }

    if (h > 1) {
        h -= 1;
    }

    if (6 * h < 1) {
        return p + ((q - p) * 6 * h);
    }

    if (2 * h < 1) {
        return q;
    }

    if (3 * h < 2) {
        return p + ((q - p) * 6 * ((2.0f / 3.0f) - h));
    }

    return p;
}
Yona Appletree
  • 8,801
  • 6
  • 35
  • 52
xtempore
  • 5,260
  • 4
  • 36
  • 43
4

I found the built-in method for HSB (which is not the same as HSL, but is similar)

[Color.getHSBColor(float h, float s, float b)](http://docs.oracle.com/javase/7/docs/api/java/awt/Color.html#getHSBColor(float,%20float,%20float))
Yona Appletree
  • 8,801
  • 6
  • 35
  • 52
Eric
  • 95,302
  • 53
  • 242
  • 374
  • 8
    Well, HSB is not exactly the same as HSL. – Andrei Fierbinteanu Jun 08 '10 at 14:11
  • 2
    e.g. `Color.getHSBColor(0, 1, 1)` would return the color red, but if you wanted the color for (H=0, S=1, L=1) you should get white. – Andrei Fierbinteanu Jun 08 '10 at 14:37
  • @Andrei: Indeed. http://en.wikipedia.org/wiki/HSL_and_HSV: "HSV stands for hue, saturation, and value, and is also often called HSB (B for brightness)." – JAB Jun 08 '10 at 16:52
  • I'm voting this down because the results are very wrong when you feed an HSL value into here. – bmargulies Aug 06 '12 at 13:16
  • 2
    @downvoters: Why does this get downvotes, yet the identical and later answer at the top of page getupvotes? – Eric Jul 12 '13 at 08:10
  • 2
    That's a good question. As the question is written, both your answer and the highest voted answer are actually incorrect, making the assumption that HSL == HSB. I have posted an answer with links to a good article about HSL (not HSB) in java below. – Yona Appletree Dec 30 '13 at 18:34
  • @Hypher: For my particular application, the important part was the `H`, so this was close enough – Eric Dec 30 '13 at 23:06
1

Maybe this will help. The JDK doesn't seem to be very helpful when wanting to use colors in another color space.

Edit: In ColorSpace.getName(idx) there's this little snippet:

 case ColorSpace.TYPE_HLS:
                    compName = new String[] {"Hue", "Lightness", 
                                             "Saturation"};

so it was what you thought, but looking at the type hierarchy of ColorSpace it doesn't seem to be used or implemented in any way anywhere. ColorSpace is extended by only two other classes BogusColorSpace and ICC_ColorSpace, so I'm guessing they're expecting developers to create their own implementations for different color spaces.

Andrei Fierbinteanu
  • 7,656
  • 3
  • 31
  • 45
0

If your input is swing/awt widgets, then with Java 7 JColorChooser you can get Color by HSV and HSL spaces. http://java.dzone.com/articles/new-color-chooser-jdk-7

Waldemar Wosiński
  • 1,490
  • 17
  • 28