I am wondering if there is single one matched HSL color for a given RGB color?
Based on existing formula converting RGB to HSL, it is yes.
However, I want to know if my assertion above is true?
I am wondering if there is single one matched HSL color for a given RGB color?
Based on existing formula converting RGB to HSL, it is yes.
However, I want to know if my assertion above is true?
Relying solely on common sense:
RGB is defined by
Red ranges from 0 to 255 (256 options)
Green ranges from 0 to 255 (256 options)
Blue ranges from 0 to 255 (256 options)
Total number of RGB options = 256*256*256 = 16,777,216
HSL is defined by:
Hue - ranges from 0 to 359 (360 options)
Saturation - ranges from 0 to 100 (101 options)
Lightness(luminosity) - ranges from 0 to 100 (101 options)
Total number of HSL options = 360*101*101 = 3,672,360
My guess here is that since the total number of RGB colors is much higher than that of HSL colors, it's impossible to have 1 - 1 correspondence between the formats.
Will a convertor convert every RGB value to an HSL value - absolutely - it will round off to the closest value it can assign.
rgb(198, 26, 78)
= hsl(341.9, 76.8, 43.9)
can I hope to increase the lightness to exact 50 (from 43.9) and still be able to recreate the same RGB values by adjusting either hue or saturation or both?
Commented
Nov 22, 2020 at 0:04
HSL is a polar(ish), or more accurately hexagon, transformation of the standard RGB color space as such each value only corresponds to one possible RGB triplet. This is however what would happen if we assume the numbers are numbers in the mathematical sense.
However, the individual implementation details of each software do matter. It may be that if you convert this into integer to integer, float to integer processing. That a individual colors drop out on account of rounding or implementation mistakes.
This may or may not matter to you. As it applies to every implementation of everything on a computer. Personally I never think of color as byte sized values. Instead i just think of each channel as it would be a floating point number from 0 to unbounded whit 1 being maximum display value. Why? Because this works if my channel depth is suddenly 12 bit or 16 or float or whatever. I can just normalize it. So i Personally do not care, if the details become a limit i just upgrade my processing to higher bit order.
Tested it out programmatically. It seems there is indeed one-to-one relation.
At least for complex colors (e.g. 198, 26, 78), and not colors like (128, 128, 128)
I personally wanted to know, for example if in rgb(198, 26, 78)
= hsl(341.9, 76.8, 43.9)
I could set the lightness to exact 50 (from 43.9) and still be able to recreate the same RGB values by adjusting either hue or saturation or both. It seems not. However if I relaxed the RGB values to be ~10 away from the original I could find a few corresponding HSL values.
Code (NodeJS):
const R = 198;
const G = 26;
const B = 78;
const step = 0.001;
const hslValues = new Set;
for (let h = 0; h < 1; h += step) {
for (let s = 0; s < 1; s += step) {
for (let l = 0; l < 1; l += step) {
const [r, g, b] = hslToRgb(h, s, l)
if (R === r && G === g && B === b) {
hslValues.add(`${h}, ${s}, ${l}`);
// console.log(`${hslValues.size} HSL values found for given RGB`);
}
}
}
}
console.log(`${hslValues.size} HSL values found for given RGB`);
console.log(hslValues);
function hslToRgb(h, s, l) {
/* https://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion */
var r, g, b;
if (s == 0) {
r = g = b = l; // achromatic
} else {
var hue2rgb = function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
RGB(128,128,128)
(in other words colors with saturation = 0
), you would have to allow hue to be null
. That way you could set up your code to work backwards as well.