I'm trying to convert a rgb color to hsl in Java, i have searched for many codes that explain how you convert rgb to hsl, i now have saturation and lightness working, but the hue value is incorrect
I am now trying to convert rgb to hsl and then back.
the rgb values i am using are
red: 54 green: 43 blue: 21
The hsl values i get are
hue: 260 saturation: 44 lightness: 15
I tried to convert the rgb values to hsl at https://www.rapidtables.com/convert/color/rgb-to-hsl.html
The values i get there are
hue: 40 saturation: 44.0 lightness: 14.7
Does anyone know what i'm doing wrong in converting rgb to hsl? Here is my code
public static Map<String, Integer> rgbToHsl(Integer red, Integer green, Integer blue){
Float redDouble = ((float)red) / 255.0f;
Float greenDouble = ((float)green) / 255.0f;
Float blueDouble = ((float)blue) / 255.0f;
Float max = Math.max(Math.max(redDouble, greenDouble), blueDouble);
Float min = Math.min(Math.min(redDouble, greenDouble), blueDouble);
Float chroma = max - min;
Float hue = chroma == 0.0f ? 0.0f :
(max == redDouble ? (greenDouble - blueDouble) / chroma :
(max == greenDouble ? 2f + (blueDouble - redDouble) / chroma :
4f + (redDouble - greenDouble) / chroma));
Float lightness = (max + min) * 0.5f;
Float saturation = chroma == 0.0f ? 0.0f : (lightness > 0.5f ? chroma / (2.0f - max - min) : chroma / (max + min));
return Map.ofEntries(
Map.entry("hue", (int) Math.round(hue * 60)),
Map.entry("saturation", (int) Math.round(saturation * 100)),
Map.entry("lightness", (int) Math.round(lightness * 100))
);
}
When you use boxed Float
s everywhere, the Math.max(Math.max(a, b), c)
will unbox the arguments a
, b
and c
, then perform the computation, then box them back into a Float
.
The result will be a new object, unequal to all three a
, b
and c
.
Therefore, the identity comparisons max == redDouble
and max == greenDouble
will always be false
.
Eliminate the boxed types, use float
s everywhere, it's both faster and clearer.
Even better: never use either ==
or equals
on any kind of floating-point values. See, for example, how here additional boolean flags were used. Booleans are not susceptible to tiny rounding errors.