我正在寻找一个算法之间的HSL颜色转换为RGB。
在我看来,HSL不是很广泛地使用,所以我没有太多的运气寻找一个转换器。
我正在寻找一个算法之间的HSL颜色转换为RGB。
在我看来,HSL不是很广泛地使用,所以我没有太多的运气寻找一个转换器。
当前回答
我是这样做的,这很容易记住,把RGB想象成一个轮子上的三条辐条,相隔120度。
H = hue (0-360)
S = saturation (0-1)
L = luminance (0-1)
R1 = SIN( H ) * L
G1 = SIN( H + 120 ) * L
B1 = SIN( H + 240 ) * L
棘手的部分是饱和度,即缩小到这三者的平均值。
AVERAGE = (R1 + G1 + B1) / 3
R2 = ((R1 - AVERAGE) * S) + AVERAGE
G2 = ((G1 - AVERAGE) * S) + AVERAGE
B2 = ((B1 - AVERAGE) * S) + AVERAGE
RED = R2 * 255
GREEN = G2 * 255
BLUE = B2 * 255
其他回答
我从Brandon Mathis的HSL Picker源代码中得到了这个。
它最初是用CoffeeScript编写的。我使用在线转换器将其转换为JavaScript,并拿出验证用户输入是否为有效RGB值的机制。这个答案适用于我的用例,因为我发现这篇文章上投票最多的答案不能产生有效的HSL值。
注意,它返回一个hsla值,表示不透明/透明。0是完全透明的,1是完全不透明的。
function rgbToHsl(rgb) {
var a, add, b, diff, g, h, hue, l, lum, max, min, r, s, sat;
r = parseFloat(rgb[0]) / 255;
g = parseFloat(rgb[1]) / 255;
b = parseFloat(rgb[2]) / 255;
max = Math.max(r, g, b);
min = Math.min(r, g, b);
diff = max - min;
add = max + min;
hue = min === max ? 0 : r === max ? ((60 * (g - b) / diff) + 360) % 360 : g === max ? (60 * (b - r) / diff) + 120 : (60 * (r - g) / diff) + 240;
lum = 0.5 * add;
sat = lum === 0 ? 0 : lum === 1 ? 1 : lum <= 0.5 ? diff / add : diff / (2 - add);
h = Math.round(hue);
s = Math.round(sat * 100);
l = Math.round(lum * 100);
a = parseFloat(rgb[3]) || 1;
return [h, s, l, a];
}
H, S, L在[0,1]范围内:
ConvertHslToRgb: function (iHsl)
{
var min, sv, sextant, fract, vsf;
var v = (iHsl.l <= 0.5) ? (iHsl.l * (1 + iHsl.s)) : (iHsl.l + iHsl.s - iHsl.l * iHsl.s);
if (v === 0)
return { Red: 0, Green: 0, Blue: 0 };
min = 2 * iHsl.l - v;
sv = (v - min) / v;
var h = (6 * iHsl.h) % 6;
sextant = Math.floor(h);
fract = h - sextant;
vsf = v * sv * fract;
switch (sextant)
{
case 0: return { r: v, g: min + vsf, b: min };
case 1: return { r: v - vsf, g: v, b: min };
case 2: return { r: min, g: v, b: min + vsf };
case 3: return { r: min, g: v - vsf, b: v };
case 4: return { r: min + vsf, g: min, b: v };
case 5: return { r: v, g: min, b: v - vsf };
}
}
下面是GLSL中快速、超级简单、无分支的版本:
vec3 hsl2rgb( vec3 c ) {
vec3 rgb = clamp(abs(mod(c.x*6.0 + vec3(0.0, 4.0, 2.0), 6.0)-3.0)-1.0, 0.0, 1.0);
return c.z + c.y * (rgb-0.5)*(1.0-abs(2.0*c.z-1.0));
}
没有比这更短的了~
原始概念验证的链接:https://www.shadertoy.com/view/XljGzV
(免责声明:不是我的代码!)
这里是修改后的javascript函数,它在0-360度集输出Hue。
function rgbToHsl(r, g, b) {
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min){
h = s = 0; // achromatic
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d ; break;
case g: h = 2 + ( (b - r) / d); break;
case b: h = 4 + ( (r - g) / d); break;
}
h*=60;
if (h < 0) h +=360;
}
return([h, s, l]);
}
alert(rgbToHsl(125,115,145));
维基百科上关于HSL和HSV的文章包含了一些公式。计算有点棘手,所以看一下现有的实现可能会有用。