我正在寻找一个算法之间的HSL颜色转换为RGB。
在我看来,HSL不是很广泛地使用,所以我没有太多的运气寻找一个转换器。
我正在寻找一个算法之间的HSL颜色转换为RGB。
在我看来,HSL不是很广泛地使用,所以我没有太多的运气寻找一个转换器。
当前回答
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 };
}
}
其他回答
如果你正在寻找一些完全符合HSL和RGB的CSS语义的东西,你可以使用css3规范中指定的算法,它如下:
HOW TO RETURN hsl.to.rgb(h, s, l):
SELECT:
l<=0.5: PUT l*(s+1) IN m2
ELSE: PUT l+s-l*s IN m2
PUT l*2-m2 IN m1
PUT hue.to.rgb(m1, m2, h+1/3) IN r
PUT hue.to.rgb(m1, m2, h ) IN g
PUT hue.to.rgb(m1, m2, h-1/3) IN b
RETURN (r, g, b)
HOW TO RETURN hue.to.rgb(m1, m2, h):
IF h<0: PUT h+1 IN h
IF h>1: PUT h-1 IN h
IF h*6<1: RETURN m1+(m2-m1)*h*6
IF h*2<1: RETURN m2
IF h*3<2: RETURN m1+(m2-m1)*(2/3-h)*6
RETURN m1
我相信这是这里其他一些答案的来源。
一个hsl|的颜色值,设置在javascript,将立即 所有你需要做的是,然后访问 计算样式值
document.body.style.color = 'hsla(44, 100%, 50%, 0.8)';
console.log(window.getComputedStyle(document.body).color);
// displays: rgba(255, 187, 0, 0.8)
从技术上讲,我想,这甚至不是任何一行代码-这是 自动完成。所以,取决于你的环境,你 也许这样就能逃过一劫。并不是说没有 这里有很多深思熟虑的回复。我不知道你的 目标是。
现在,如果你想从rbg|a转换到hsl|a呢?
简短而精确- JS
使用这个JS代码(更多:rgb2hsl, hsv2rgb rgb2hsv和hsl2hsv) - php版本在这里
// input: h as an angle in [0,360] and s,l in [0,1] - output: r,g,b in [0,1]
function hsl2rgb(h,s,l)
{
let a=s*Math.min(l,1-l);
let f= (n,k=(n+h/30)%12) => l - a*Math.max(Math.min(k-3,9-k,1),-1);
return [f(0),f(8),f(4)];
}
// oneliner version let hsl2rgb = (h,s,l, a=s*Math.min(l,1-l), f= (n,k=(n+h/30)%12) => l - a*Math.max(Math.min(k-3,9-k,1),-1)) => [f(0),f(8),f(4)]; // r,g,b are in [0-1], result e.g. #0812fa. let rgb2hex = (r,g,b) => "#" + [r,g,b].map(x=>Math.round(x*255).toString(16).padStart(2,0) ).join(''); console.log(`hsl: (30,0.2,0.3) --> rgb: (${hsl2rgb(30,0.2,0.3)}) --> hex: ${rgb2hex(...hsl2rgb(30,0.2,0.3))}`); // --------------- // UX // --------------- rgb= [0,0,0]; hs= [0,0,0]; let $ = x => document.querySelector(x); function changeRGB(i,e) { rgb[i]=e.target.value/255; hs = rgb2hsl(...rgb); refresh(); } function changeHS(i,e) { hs[i]=e.target.value/(i?255:1); rgb= hsl2rgb(...hs); refresh(); } function refresh() { rr = rgb.map(x=>x*255|0).join(', ') hh = rgb2hex(...rgb); tr = `RGB: ${rr}` th = `HSL: ${hs.map((x,i)=>i? (x*100).toFixed(2)+'%':x|0).join(', ')}` thh= `HEX: ${hh}` $('.box').style.backgroundColor=`rgb(${rr})`; $('.infoRGB').innerHTML=`${tr}`; $('.infoHS').innerHTML =`${th}\n${thh}`; $('#r').value=rgb[0]*255; $('#g').value=rgb[1]*255; $('#b').value=rgb[2]*255; $('#h').value=hs[0]; $('#s').value=hs[1]*255; $('#l').value=hs[2]*255; } function rgb2hsl(r,g,b) { let a=Math.max(r,g,b), n=a-Math.min(r,g,b), f=(1-Math.abs(a+a-n-1)); let h= n && ((a==r) ? (g-b)/n : ((a==g) ? 2+(b-r)/n : 4+(r-g)/n)); return [60*(h<0?h+6:h), f ? n/f : 0, (a+a-n)/2]; } refresh(); .box { width: 50px; height: 50px; margin: 20px; } body { display: flex; } <div> <input id="r" type="range" min="0" max="255" oninput="changeRGB(0,event)">R<br> <input id="g" type="range" min="0" max="255" oninput="changeRGB(1,event)">G<br> <input id="b" type="range" min="0" max="255" oninput="changeRGB(2,event)">B<br> <pre class="infoRGB"></pre> </div> <div> <div class="box hsl"></div> </div> <div> <input id="h" type="range" min="0" max="360" oninput="changeHS(0,event)">H<br> <input id="s" type="range" min="0" max="255" oninput="changeHS(1,event)">S<br> <input id="l" type="range" min="0" max="255" oninput="changeHS(2,event)">L<br> <pre class="infoHS"></pre><br> </div>
以下是我在wiki +错误分析中发现并精确描述的公式,
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 };
}
}
由于circuitpython不支持colorsys(或目前移植到),如果你试图在树莓派上处理这个转换,下面的工作(受制于本线程其他地方提到的舍入精度限制):
def hslToRgb (h, s, l): #in range 0-1 for h,s,l
if s == 0:
r = g = b = l #achromatic
else:
def hue2rgb(p, q, t):
if t < 0: t += 1
if t > 1: t -= 1
if t < 1.0 / 6.0: return p + (q - p) * 6 * t
if t < 1.0 / 2.0: return q
if t < 2.0 / 3.0: return p + (q - p) * ((2.0 / 3.0) - t) * 6
return p
if l < 0.5:
q = l * (1 + s)
else:
q = l + s - l * s
p = 2 * l - q
r = hue2rgb(p, q, h + 1.0/3.0)
g = hue2rgb(p, q, h)
b = hue2rgb(p, q, h - 1.0/3.0)
return [round(r * 255), round(g * 255), round(b * 255)]