This converter assumes H, S, and L are contained in the set [0, 1].
But I want H to be between [0, 359] (0 and 359 included) and S & L between [0, 100] (0 and 100 included) and I don't know how to do it (in Java as well).
I took this converter from here.
public class testdos {
public static void main(String[] args) {
// hslToRgb([0, 359], [0, 100], [0, 100]);
}
public static int[] hslToRgb(float h, float s, float l) {
// i added this sysout line
System.out.println("HSL(" + h + "," + s + "," + l + ")");
float r, g, b;
if (s == 0f) {
r = g = b = l; // achromatic
} else {
float q = l < 0.5f ? l * (1 + s) : l + s - l * s;
float p = 2 * l - q;
r = hueToRgb(p, q, h + 1f / 3f);
g = hueToRgb(p, q, h);
b = hueToRgb(p, q, h - 1f / 3f);
}
int[] rgb = { to255(r), to255(g), to255(b) };
// and i added this to print it, don't know if its the best way to do it
System.out.print("RGB(");
for (int i = 0; i < rgb.length; i++) {
if ((i + 1) != rgb.length) {
System.out.print(rgb[i] + ",");
}
else {
System.out.print(rgb[i]);
}
}
System.out.println(")");
return rgb;
}
public static int to255(float v) {
return (int) Math.min(255, 256 * v);
}
/** Helper method that converts hue to rgb */
public static float hueToRgb(float p, float q, float t) {
if (t < 0f)
t += 1f;
if (t > 1f)
t -= 1f;
if (t < 1f / 6f)
return p + (q - p) * 6f * t;
if (t < 1f / 2f)
return q;
if (t < 2f / 3f)
return p + (q - p) * (2f / 3f - t) * 6f;
return p;
}
}
The hslToRgb() method you provided accepts three parameters of float
data type. The value range that must be provided to all of these parameters is: 0.0f to 1.0f
:
int[] hslToRgb(float h, float s, float l) { ... }
Instead you want to supply a specific range values to these parameters which in turn makes the method much easier to utilize in layman's terms with respect to what needs to actually be supplied.
H (0° to 360° as in Degrees)
S (0% to 100% as in Percent)
L (0% to 100% as in Percent)
It's all a matter of doing a little division. This can be done as the parameters are supplied to the method or built into the method which appears to be what you want. The latter is somewhat more advantageous since you don't need to remember the formula (regardless of how simple it is) to carry out those divisions when applying the arguments to the hslToRgb() method.
Doing the math before passing arguments:
// Hue is: 65° Saturation is: 36% Lightness is: 87%
float hue = (float) 65/360;
float saturation = (float) 36/100;
float lightness = (float) 87/100;
int[] rgb = hslToRgb(hue, saturation, lightness);
Doing the math when passing arguments:
// Hue is: 65° Saturation is: 36% Lightness is: 87%
int[] rgb = hslToRgb((float)65/360, (float)36/100, (float)87/100);
Who cares! Let the method figure it out:
// Hue is: 65° Saturation is: 36% Lightness is: 87%
int[] rgb = hslToRgb(65, 36, 87);
This last example requires a little bit of code to be added to the hslToRgb() method. It's nothing major but before we get into that you need to be sure to realize that for color accuracy, Hue, Saturation, and Lightness arguments can be given respectively in floating point degree and floating point percentage values. In other words, supplying arguments such as:
int[] rgb = hslToRgb(65, 36, 87);
AND
int[] rgb = hslToRgb(65.8, 36.2, 87.5);
are to be considered valid calls with valid arguments. With the slight code addition to the hslToRgb() method, either or can be supplied, for example:
int[] rgb = hslToRgb(0.1806f, 36, 87.5);
This is a valid call with valid arguments and will produce the very same RGB values as the other above examples.
Modifying the hslToRgb() method:
Simply add these three lines of code to the top of the hslToRGB() method:
public static int[] hslToRGB(float h, float s, float l) {
if (h > 1.0f) { h = (h < 0 ? 0 : h > 360 ? 360 : h) / 360; }
if (s > 1.0f) { s = (s < 0 ? 0 : s > 100 ? 100 : s) / 100; }
if (l > 1.0f) { l = (l < 0 ? 0 : l > 100 ? 100 : l) / 100; }
// .... the rest of method code here ....
}
What are these three lines of code doing?
With these lines of code the Hue (h) argument can be supplied as a set [0.0 to 1.0] or a set [0.0 to 360.0] or a set [0 to 360]. The Saturation (s) and Lightness (l) arguments can be supplied as a set [0.0 to 1.0] or a set [0.0 to 100.0] or a set [0 to 100]. If any argument supplied is less than its minimum range (0) then it is defaulted to that arguments specific minimum which for all arguments would be 0. On the same hand, if any argument supplied is greater than its maximum range then it is defaulted to that arguments specific maximum.
Since all three lines of code are basically doing the same thing for each specific argument, we'll explain the first line:
if (h > 1.0f) { h = (h < 0 ? 0 : h > 360 ? 360 : h) / 360; }
The condition for the if
statement (h > 1.0f
) checks to see if the supplied Hue (h) argument is within the set of [0.0 to 1.0]. If the argument supplied is greater than 1.0 then it must be supplied as a literal degree value and the if
statement condition is true therefore running the code contained within this statement's code block which consists of nested Ternary Operator statements. If the if
statement condition is false then the supplied value is merely used. Ultimately, if the condition is true then we want to take the supplied argument and divide it by 360 but first we use the nested Ternary Operator statements to ensure the argument supplied is within valid range (0 to 360):
h < 0 ? 0 :
If the supplied argument (h) is less than 0 (such as an arbitrary value of -22 or -0.202) then the h is set to hold a default of 0 otherwise we check to see if the argument value is greater then 360:
: h > 360 ? 360 :
If the supplied argument (h) is greater than 360 (such as an arbitrary value of 365 or 378.8) then the h is set to hold a default of 360 otherwise it is deemed that the argument supplied is indeed within the proper range and we'll use it therefore dividing the supplied value by 360;
: h) / 360
How you might use this method:
int[] rgb = hslToRGB(65, 36, 87);
System.out.println("RGB is: " + java.util.Arrays.toString(rgb));
String hex = "#" + Integer.toHexString(new Color(rgb[0], rgb[1], rgb[2]).getRGB() & 0x00ffffff);
System.out.println("In Hexadecimal: " + hex.toUpperCase());
Console Output:
RGB is: [232, 234, 210]
In Hexadecimal: #E8EAD2