我正在寻找一个算法之间的HSL颜色转换为RGB。
在我看来,HSL不是很广泛地使用,所以我没有太多的运气寻找一个转换器。
我正在寻找一个算法之间的HSL颜色转换为RGB。
在我看来,HSL不是很广泛地使用,所以我没有太多的运气寻找一个转换器。
当前回答
@Mohsen代码的PHP实现(包括Test!)
很抱歉重新发布这篇文章。但我真的没有看到任何其他实现可以提供我所需的质量。
/**
* Converts an HSL color value to RGB. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes h, s, and l are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255].
*
* @param {number} h The hue
* @param {number} s The saturation
* @param {number} l The lightness
* @return {Array} The RGB representation
*/
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;
}
function hslToRgb($h, $s, $l){
if($s == 0){
$r = $l;
$g = $l;
$b = $l; // achromatic
}else{
$q = $l < 0.5 ? $l * (1 + $s) : $l + $s - $l * $s;
$p = 2 * $l - $q;
$r = hue2rgb($p, $q, $h + 1/3);
$g = hue2rgb($p, $q, $h);
$b = hue2rgb($p, $q, $h - 1/3);
}
return array(round($r * 255), round($g * 255), round($b * 255));
}
/* Uncomment to test * /
for ($i=0;$i<360;$i++) {
$rgb=hslToRgb($i/360, 1, .9);
echo '<div style="background-color:rgb(' .$rgb[0] . ', ' . $rgb[1] . ', ' . $rgb[2] . ');padding:2px;"></div>';
}
/* End Test */
其他回答
当你需要RGB到HSV,反之亦然:
function rgbToHsv(r, g, b)
{
r /= 255, g /= 255, b /= 255;
var min = Math.min(r, g, b),
max = Math.max(r, g, b),
delta = max - min,
h = 0, s = 0, v = max;
if (min != max)
{
s = (delta / max);
switch (max)
{
case r: h = (g - b) / delta + (g < b ? 6 : 0); break;
case g: h = (b - r) / delta + 2; break;
case b: h = (r - g) / delta + 4; break;
}
h /= 6;
}
return [h, s, v];
}
function hsvToRgb(h, s, v)
{
var step = h / (1 / 6),
pos = step - Math.floor(step), // the hue position within the current step
m = (Math.floor(step) % 2) ? (1 - pos) * v : pos * v, // mix color value adjusted to the brightness(v)
max = 1 * v,
min = (1 - s) * v,
med = m + ((1 - s) * (v - m)),
r, g, b;
switch (Math.floor(step))
{
case 0:
r = max;
g = med;
b = min;
break;
case 1:
r = med;
g = max;
b = min;
break;
case 2:
r = min;
g = max;
b = med;
break;
case 3:
r = min;
g = med;
b = max;
break;
case 4:
r = med;
g = min;
b = max;
break;
case 5:
r = max;
g = min;
b = med;
break;
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
下面是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
(免责声明:不是我的代码!)
Java版本:
/*
Converts color from HSL/A format to RGB/A format
0 <= h <= 360
0 <= s, l, a <= 1
Based on: https://en.wikipedia.org/wiki/HSL_and_HSV#:~:text=%5Bedit%5D-,HSL%20to%20RGB%5Bedit%5D,-Given%20a%20color
*/
public RGB toRGB(double h, double s, double l, Double a) {
double c = (1 - Math.abs(2 * l - 1)) * s;
double x = c * (1 - Math.abs((h / 60) % 2 - 1));
double m = l - c / 2;
int[] RGBTag = Arrays.stream(getRGBTag(c, x)).mapToInt(e -> (int)Math.round((e + m) * 255)).toArray();
return RGB(RGBTag[0], RGBTag[1], RGBTag[2], a);
}
private double[] getRGBTag(double c, double x) {
if (h < 60) {
return new double[] {c, x, 0};
} else if (h < 120) {
return new double[] {x, c, 0};
} else if (h < 180) {
return new double[] {0, c, x};
} else if (h < 240) {
return new double[] {0, x, c};
} else if (h < 300) {
return new double[] {x, 0, c};
}
return new double[] {c, 0, x};
}
简短而精确- 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 +错误分析中发现并精确描述的公式,
一个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呢?