Javascript准确地将HSB / HSV颜色转换为RGB [英] Javascript convert HSB/HSV color to RGB accurately
问题描述
我需要准确地将HSB转换为RGB,但我不知道如何解决将小数转换为整数而不进行舍入的问题。这是我在colorpicker库中的当前函数:
I need to accurately convert HSB to RGB but I am not sure how to get around the problem of turning decimals into whole numbers without rounding. This is the current function I have out of a colorpicker library:
HSBToRGB = function (hsb) {
var rgb = { };
var h = Math.round(hsb.h);
var s = Math.round(hsb.s * 255 / 100);
var v = Math.round(hsb.b * 255 / 100);
if (s == 0) {
rgb.r = rgb.g = rgb.b = v;
} else {
var t1 = v;
var t2 = (255 - s) * v / 255;
var t3 = (t1 - t2) * (h % 60) / 60;
if (h == 360) h = 0;
if (h < 60) { rgb.r = t1; rgb.b = t2; rgb.g = t2 + t3 }
else if (h < 120) { rgb.g = t1; rgb.b = t2; rgb.r = t1 - t3 }
else if (h < 180) { rgb.g = t1; rgb.r = t2; rgb.b = t2 + t3 }
else if (h < 240) { rgb.b = t1; rgb.r = t2; rgb.g = t1 - t3 }
else if (h < 300) { rgb.b = t1; rgb.g = t2; rgb.r = t2 + t3 }
else if (h < 360) { rgb.r = t1; rgb.g = t2; rgb.b = t1 - t3 }
else { rgb.r = 0; rgb.g = 0; rgb.b = 0 }
}
return { r: Math.round(rgb.r), g: Math.round(rgb.g), b: Math.round(rgb.b) };
正如您所看到的,此函数的不准确性来自Math.round
As you can see the inaccuracy in this function comes from the Math.round
推荐答案
来自 Parthik Gosar 的链接 此评论稍作修改,允许您单独输入每个值或一次性输入所有值
From Parthik Gosar's link in this comment with slight modification to let you enter each value independently or all at once as an object
/* accepts parameters
* h Object = {h:x, s:y, v:z}
* OR
* h, s, v
*/
function HSVtoRGB(h, s, v) {
var r, g, b, i, f, p, q, t;
if (arguments.length === 1) {
s = h.s, v = h.v, h = h.h;
}
i = Math.floor(h * 6);
f = h * 6 - i;
p = v * (1 - s);
q = v * (1 - f * s);
t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0: r = v, g = t, b = p; break;
case 1: r = q, g = v, b = p; break;
case 2: r = p, g = v, b = t; break;
case 3: r = p, g = q, b = v; break;
case 4: r = t, g = p, b = v; break;
case 5: r = v, g = p, b = q; break;
}
return {
r: Math.round(r * 255),
g: Math.round(g * 255),
b: Math.round(b * 255)
};
}
此代码需要 0< = h,s ,v< = 1
,如果你使用度数或弧度,记得将它们分开。
This code expects 0 <= h, s, v <= 1
, if you're using degrees or radians, remember to divide them out.
返回的 0< = r,g,b< = 255
四舍五入到最近的整数。如果您不想要此行为,请从返回的对象中删除 Math.round
。
The returned 0 <= r, g, b <= 255
are rounded to the nearest Integer. If you don't want this behaviour remove the Math.round
s from the returned object.
相反(减少分割)
/* accepts parameters
* r Object = {r:x, g:y, b:z}
* OR
* r, g, b
*/
function RGBtoHSV(r, g, b) {
if (arguments.length === 1) {
g = r.g, b = r.b, r = r.r;
}
var max = Math.max(r, g, b), min = Math.min(r, g, b),
d = max - min,
h,
s = (max === 0 ? 0 : d / max),
v = max / 255;
switch (max) {
case min: h = 0; break;
case r: h = (g - b) + d * (g < b ? 6: 0); h /= 6 * d; break;
case g: h = (b - r) + d * 2; h /= 6 * d; break;
case b: h = (r - g) + d * 4; h /= 6 * d; break;
}
return {
h: h,
s: s,
v: v
};
}
此代码将输出 0< = h, s,v< = 1
,但这次需要 0< = r,g,b< = 255
(不需要)是一个整数)
This code will output 0 <= h, s, v <= 1
, but this time takes any 0 <= r, g, b <= 255
(does not need to be an integer)
为了完整性,
function HSVtoHSL(h, s, v) {
if (arguments.length === 1) {
s = h.s, v = h.v, h = h.h;
}
var _h = h,
_s = s * v,
_l = (2 - s) * v;
_s /= (_l <= 1) ? _l : 2 - _l;
_l /= 2;
return {
h: _h,
s: _s,
l: _l
};
}
function HSLtoHSV(h, s, l) {
if (arguments.length === 1) {
s = h.s, l = h.l, h = h.h;
}
var _h = h,
_s,
_v;
l *= 2;
s *= (l <= 1) ? l : 2 - l;
_v = (l + s) / 2;
_s = (2 * s) / (l + s);
return {
h: _h,
s: _s,
v: _v
};
}
所有这些值都应在 0范围内
到 1
。对于 HSL< - > RGB
通过 HSV 进行。
All of these values should be in the range 0
to 1
. For HSL<->RGB
go via HSV.
这篇关于Javascript准确地将HSB / HSV颜色转换为RGB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!