javascript 将 HSB/HSV 颜色转换为 HSL
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3423214/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert HSB/HSV color to HSL
提问by NVI
Ho do I convert HSB color to HSL?
如何将 HSB 颜色转换为 HSL?
Photoshop shows HSB color in its color picker. HSL color can be used in CSS.
Photoshop 在其颜色选择器中显示 HSB 颜色。HSL 颜色可以在 CSS 中使用。
I tried this JS:
我试过这个JS:
function hsb2hsl(h, s, b) {
return {
h: h,
s: s,
l: b-s/2
}
}
But hsb2hsl(0, 100, 50).l == 0instead of 25
但hsb2hsl(0, 100, 50).l == 0不是25
Update:Can I do that without converting HSB → RGB → HSL?
更新:我可以在不转换 HSB → RGB → HSL 的情况下做到这一点吗?
采纳答案by Chowlett
I'm afraid my Javascript knowledge is lacking, but you should be able to infer the conversion from http://ariya.blogspot.com/2008/07/converting-between-hsl-and-hsv.html
恐怕我的 Javascript 知识缺乏,但您应该能够从http://ariya.blogspot.com/2008/07/converting-between-hsl-and-hsv.html推断转换
回答by Bob
I think this is the most precise:
我认为这是最准确的:
function hsv_to_hsl(h, s, v) {
// both hsv and hsl values are in [0, 1]
var l = (2 - s) * v / 2;
if (l != 0) {
if (l == 1) {
s = 0
} else if (l < 0.5) {
s = s * v / (l * 2)
} else {
s = s * v / (2 - l * 2)
}
}
return [h, s, l]
}
回答by Kamil Kie?czewski
Try this (s,v,l in [0,1], wiki details, more: hsv2rgbrgb2hsvand hsl2rgbrgb2hsl)
试试这个(s,v,l in [0,1],wiki详细信息,更多:hsv2rgb rgb2hsv和hsl2rgb rgb2hsl)
let hsv2hsl = (h,s,v,l=v-v*s/2,m=Math.min(l,1-l)) => [h,m?(v-l)/m:0,l];
let hsl2hsv = (h,s,l,v=s*Math.min(l,1-l)+l) => [h, v?2-2*l/v:0, v];
let hsv2hsl = (h,s,v,l=v-v*s/2,m=Math.min(l,1-l)) => [h,m?(v-l)/m:0,l];
let hsl2hsv = (h,s,l,v=s*Math.min(l,1-l)+l) => [h, v?2-2*l/v:0, v];
console.log("hsv:["+ hsl2hsv(30,1,0.6) +"] hsl:["+ hsv2hsl(30,0.8,1) +"]");
// -------------------
// UI code
// -------------------
let $ = x => document.querySelector(x);
let c = (x,s) => $(x).style.backgroundColor=s;
let hsl=[0,1,0.5];
let hsv=hsl2hsv(...hsl);
let refreshHSV =(i,e) => {
hsv[i]= e.target.value/(i?100:1);
hsl=hsv2hsl(...hsv);
refreshView();
}
let refreshHSL =(i,e) => {
hsl[i]= e.target.value/(i?100:1);
hsv=hsl2hsv(...hsl);
refreshView();
}
let hsv2rgb = (h,s,v) => {
let f= (n,k=(n+h/60)%6) => v - v*s*Math.max( Math.min(k,4-k,1), 0);
return [f(5),f(3),f(1)];
}
let refreshView = () => {
let a= [hsl[0], (hsl[1]*100).toFixed(2), (hsl[2]*100).toFixed(2)];
let b= [hsv[0], (hsv[1]*100).toFixed(2), (hsv[2]*100).toFixed(2)];
let r= hsv2rgb(...hsv).map(x=>x*255|0);
let ta= `hsl(${a[0]},${a[1]}%,${a[2]}%)`
let tb= `hsv(${b[0]},${b[1]}%,${b[2]}%)`
let tr= `rgb(${r[0]},${r[1]},${r[2]})`
c('.hsl', tr);
$('#sv').value=hsv[1]*100;
$('#v').value =hsv[2]*100;
$('#sl').value=hsl[1]*100;
$('#l').value =hsl[2]*100;
$('.info').innerHTML=`${tr}\n${tb}\n${ta.padEnd(25)}`;
}
refreshView();
.box {
width: 50px;
height: 50px;
margin: 20px;
}
body {
display: flex;
background: white;
}
<div>
<input id="h" type="range" min="0" max="360" value="0" oninput="refreshHSV(0,event)">Hue<br>
<div class="box hsl"></div>
<pre class="info"></pre>
</div>
<div>
<input id="sv" type="range" min="0" max="100" value="0" oninput="refreshHSV(1,event)">HSV Saturation<br>
<input id="v" type="range" min="0" max="100" value="100" oninput="refreshHSV(2,event)">HSV Value<br><br><br>
<input id="sl" type="range" min="0" max="100" value="0" oninput="refreshHSL(1,event)">HSL Saturation<br>
<input id="l" type="range" min="0" max="100" value="100" oninput="refreshHSL(2,event)">HSL Lightness<br>
</div>
回答by ericsoco
Stephen Morley seems to have nailed it here.
斯蒂芬莫利似乎已经把它钉在这里了。
Specifically:
具体来说:
/* Calculates and stores the HSL components of this HSVColour so that they can
* be returned be the getHSL function.
*/
function calculateHSL(){
// determine the lightness in the range [0,100]
var l = (2 - hsv.s / 100) * hsv.v / 2;
// store the HSL components
hsl =
{
'h' : hsv.h,
's' : hsv.s * hsv.v / (l < 50 ? l * 2 : 200 - l * 2),
'l' : l
};
// correct a division-by-zero error
if (isNaN(hsl.s)) hsl.s = 0;
}
He uses [0-360] for hue and [0-100] for the other values.
他使用 [0-360] 表示色调,使用 [0-100] 表示其他值。
回答by GalacticCowboy
First of all, your order of operations will result in:
首先,您的操作顺序将导致:
b - s / 2 =
50 - 100 / 2 =
50 - 50 = 0
because the division operator has higher precedence than subtraction. If you're expecting 25, you need to do (b - s) / 2instead.
因为除法运算符的优先级高于减法运算符。如果你期待 25,你需要做(b - s) / 2。
I'm not exactly sure that this result is what you want, however. Since the definitions of both B (V) and L are based on the RGB colorspace, you need at least a way to recover the values of Mand mto calculate the conversion.
但是,我不确定这个结果是否是您想要的。由于 B (V) 和 L 的定义都是基于 RGB 颜色空间的,因此您至少需要一种方法来恢复M和m的值来计算转换。
See the Wikipediaarticle for more information.
有关更多信息,请参阅维基百科文章。
回答by Vincnetas
You can try using Tinycolorlibrary. To convert from HSV to HSL you could do this
您可以尝试使用Tinycolor库。要将 HSV 转换为 HSL,您可以执行此操作
tinycolor("hsv(34, 56%, 100%)").toHslString()
tinycolor("hsv(34, 56%, 100%)").toHslString()
you should get result somethng like this : "hsl(34, 100%, 72%)"
你应该得到这样的结果:“hsl(34, 100%, 72%)”
回答by Pitoziq
There are a lot of conversion formulas between different color spaces: http://www.easyrgb.com/?X=MATH
不同颜色空间之间有很多转换公式:http: //www.easyrgb.com/?X= MATH

