我已经使用我在 Wikipedia 上找到的公式构建了一个将 RGB 转换为 HSV 的函数。 。虽然输出中的数字看起来是正确的,但它们的位置会根据较大的数字而不断变化。
示例:
Given HSV: [204, 100, 94]
Expected RGB: [ 0, 144, 240]
Output RGB: [240, 0, 144]
Given HSV: [240, 100, 94]
Expected RGB: [ 0, 0, 240]
Output RGB: [240, 0, 0]
Given HSV: [120, 100, 94]
Expected RGB: [ 0, 240, 0]
Output RGB: [240, 0, 0]
这个是正确的,因为红色恰好是最大的数字:
Given HSV: [ 0, 100, 94]
Expected RGB: [240, 0, 0]
Output RGB: [240, 0, 0]
这是函数:
function hsvRGB(h, s, v) {
h /= 60, s /= 100, v /= 100; // Convert [deg, %, %] to ranges 0-6, 0-1, 0-1
var r, g, b; // Set up for later
var r1, g1, b1; // Set up for later
var c = v*s; // Chroma
var x = c*(1-Math.abs(h%2-1));
if ( h <= 0 ) [r1, g1, b1] = [0, 0, 0];
if ( 0 <= h <= 1 ) [r1, g1, b1] = [c, x, 0];
if ( 1 < h <= 2 ) [r1, g1, b1] = [x, c, 0];
if ( 2 < h <= 3 ) [r1, g1, b1] = [0, c, x];
if ( 3 < h <= 4 ) [r1, g1, b1] = [0, x, c];
if ( 4 < h <= 5 ) [r1, g1, b1] = [x, 0, c];
if ( 5 < h <= 6 ) [r1, g1, b1] = [c, 0, x];
var m = v-c;
[r, g, b] = [r1 + m, g1 + m, b1 + m];
return [r*255, g*255, b*255]; // Output 0-255 instead of 0-1
}
我一直在对照维基百科上的公式检查并重新检查我的函数,我看不到它所做的任何我没有看到的事情,但我已经研究这个很久了,我可能只是需要第二双眼睛。
最佳答案
首先,最重要的问题是,虽然
if ( 0 <= h <= 1 )
看起来很合理,但它并不像人们想象的那样有效。它被 JavaScript 解释,就好像它是被编写的
if ((0 <= h) <= 1)
JavaScript 比较运算符返回 bool 结果,因此虽然它在语法上是正确的,但它所做的事情与检查 h
是否在 0
和1
。
由于该算法使用输入值的 H Angular 在六种不同场景之一之间进行选择,因此可以使用 switch
语句来更简单地完成整个事情(如中所述)对问题的评论)。首先,编写的代码处理 h
为负数的情况,这很好,但由于它是一个 Angular 值,因此可以安全地将其强制进入范围 [0, 360)
:
function hsvRGB(h, s, v) {
while (h < 0) h += 360; // could be smarter but just for illustration
h = h % 360;
h /= 60, s /= 100, v /= 100; // Convert [deg, %, %] to ranges 0-6, 0-1, 0-1
所以现在 h
位于 0
和 6
之间;它可能是 0
,但永远不会完全是 6
。然后我们可以使用 switch
来区分情况:
switch (Math.floor(h)) {
case 0: [r1, g1, b1] = [c, x, 0]; break;
case 1: [r1, g1, b1] = [x, c, 0]; break;
case 2: [r1, g1, b1] = [0, c, x]; break;
case 3: [r1, g1, b1] = [0, x, c]; break;
case 4: [r1, g1, b1] = [x, 0, c]; break;
case 5: [r1, g1, b1] = [c, 0, x]; break;
}
关于Javascript:将 HSV 转换为 RGB,输出正确但已打乱,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53522419/