我可以将HSB颜色转换为HSL吗?
Photoshop在其颜色选择器中显示HSB颜色。 HSL颜色可以在CSS中使用。
我试过这个JS:
function hsb2hsl(h, s, b) { return { h: h, s: s, l: b-s/2 } }
但hsb2hsl(0, 100, 50).l == 0
代替25
更新:我可以在不转换HSB→RGB→HSL的情况下执行此操作吗?
答案 0 :(得分:20)
让我们看看实际上是H SB (V),H SL ,以及如何构建:
对于HSB和HSL,
Hue 颜色值从0
到360
度(其中 0
为红色)。
在HUE之上应用此线性渐变图层
让我们看看如何做SB> SL> SB有:
var H = 360, // Values 0-360 but we'll use red by default
SB = {s:0, b:0}, // Values 0-1
SL = {s:0, l:0}; // Values 0-1
function sb2sl() {
SL.l = (2 - SB.s) * SB.b / 2;
SL.s = SL.l&&SL.l<1 ? SB.s*SB.b/(SL.l<0.5 ? SL.l*2 : 2-SL.l*2) : SL.s;
}
function sl2sb() {
var t = SL.s * (SL.l<0.5 ? SL.l : 1-SL.l);
SB.b = SL.l+t;
SB.s = SL.l>0 ? 2*t/SB.b : SB.s ;
}
要转换为非浮动的%
百分比值,请执行以下操作:
(SB.s * 100 |0) // |0 removes floats
这是一个实际的例子:
var $SB = $("#SB"), $SBdot = $SB.find("span"), $SBres = $("#SBres"),
$SL = $("#SL"), $SLdot = $SL.find("span"), $SLres = $("#SLres"),
size = $SB.width(), // the area W,H size
SB = {s:0, b:0}, // Values 0-1
SL = {s:0, l:0}; // Values 0-1
function sb2sl() {
SL.l = (2 - SB.s) * SB.b / 2;
SL.s = SL.l&&SL.l<1 ? SB.s*SB.b/(SL.l<0.5 ? SL.l*2 : 2-SL.l*2) : SL.s;
}
function sl2sb() {
var t = SL.s * (SL.l<0.5 ? SL.l : 1-SL.l);
SB.b = SL.l+t;
SB.s = SL.l>0 ? 2*t/SB.b : SB.s ;
}
$SB.add( $SL ).on("mousemove", function(e){
var cr = this.getBoundingClientRect();
var x = e.clientX - cr.left |0;
var y = e.clientY - cr.top |0;
if(this.id==="SB") { // Mouse over #SB ?
// Mouse position to 0-1 SB values
SB.s = x / (size-1);
SB.b = 1- y / (size-1);
// Convert inally SB to SL
sb2sl();
// Move dots
$SBdot.css({left:x, top:y});
$SLdot.css({left: SL.s*size, top:size-(SL.l*size)});
}else{
// Mouse position to SL 0-1 values
SL.s = x / (size-1);
SL.l = 1- y / (size-1);
// Convert finally SL to SB
sl2sb();
// Move dots
$SLdot.css({left:x, top:y});
$SBdot.css({left: SB.s*size, top:size-(SB.b*size)});
}
// Write textual results
$SBres.html("S:"+ (SB.s*100|0) +"%<br> B:"+ (SB.b*100|0)+"%");
$SLres.html("S:"+ (SL.s*100|0) +"%<br> L:"+ (SL.l*100|0)+"%");
});
&#13;
body{margin:0 20px;font:12px/1.2 sans-serif;}
body>div{display:inline-block;margin: 20px;}
#SL,
#SB{
position:relative;
width:120px; height:120px;
cursor:crosshair;
}
#SB{
background:
linear-gradient(to bottom, transparent, #000),
linear-gradient(to right, #fff, transparent),
red;
}
#SL{
background:
linear-gradient(to bottom, #fff, transparent, #000),
linear-gradient(to right, #808080, transparent),
red
}
#SL span,
#SB span{
position:absolute;
width:9px; height:9px;
margin:-4px;
border-radius:50%;
box-shadow:0 0 0 1px #fff, 0 0 0 2px #000;
pointer-events:none;
}
#SB span{left:100%; top:0;}
#SL span{left:100%; top:50%;}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<b>HSB(HSV)</b>
<div id="SB"><span></span></div>
<p id="SBres">S:100%<br>B:100%</p>
</div>
<div>
<b>HSL</b>
<div id="SL"><span></span></div>
<p id="SLres">S:100%<br>L:50%</p>
</div>
&#13;
答案 1 :(得分:9)
我认为这是最精确的:
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]
}
答案 2 :(得分:2)
首先,您的操作顺序将导致:
b - s / 2 =
50 - 100 / 2 =
50 - 50 = 0
因为除法运算符的优先级高于减法。如果您期望25,那么您需要改为(b - s) / 2
。
然而,我并不完全确定这个结果是你想要的。由于B(V)和L的定义都基于RGB颜色空间,因此至少需要一种方法来恢复 M 和 m 的值来计算转换
有关详细信息,请参阅Wikipedia文章。
答案 3 :(得分:1)
具体做法是:
/* 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;
}
他使用[0-360]表示色调,[0-100]表示其他值。
答案 4 :(得分:0)
您可以尝试使用Tinycolor库。 要将HSV转换为HSL,您可以这样做
tinycolor("hsv(34, 56%, 100%)").toHslString()
你应该得到像这样的结果:“hsl(34,100%,72%)”
答案 5 :(得分:0)
尝试一下[[0,1]中的s,v,l,Wiki sv2sl和sl2sv,以及更多内容:hsv2rgb rgb2hsv和hsl2rgb { {3}})
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;
}
<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>
答案 6 :(得分:0)
维基百科不再显示由 Kamil Kiełczewski 显示的公式。它们现在看起来像这样:
const hsvToHsl = (h, s, v, l = v * (1 - (s / 2))) => [h, l === 0 || l === 1 ? 0 : (v - l) / Math.min(l, 1 - l), l];
const hslToHsv = (h, s, l, v = l + s * Math.min(l, 1 - l)) => [h, v === 0 ? 0 : 2 * (1 - (l / v)), v];
答案 7 :(得分:-2)
我担心我的Javascript知识缺失,但您应该可以从http://ariya.blogspot.com/2008/07/converting-between-hsl-and-hsv.html推断转换
答案 8 :(得分:-2)
不同颜色空间之间有很多转换公式:http://www.easyrgb.com/?X=MATH