我搜索谷歌没有用。
如果我有以下颜色rgb(50,100,200)
。我可以使用(200-50)/200
计算HSV饱和度,即0.75
。如果想要使用不同饱和度的色调,我该如何计算?
我使用颜色选择器来获取这些测试数据:
r:50 g:100 b:200
saturation = 0.75
r:0 g:66 b:200
saturation = 1
r:100 g:134 b:200
saturation = 0.5
r:150 g:167 b:200
saturation = 0.25
我注意到饱和度发生变化时,最大值不会发生变化。 r,g,b数之间没有找到比率。
我可以使用RGB计算新的颜色,而不是先将其转换为HSV颜色吗?
答案 0 :(得分:1)
在Excel绘图和复杂公式构建的数小时之后,解决方案并不是那么复杂!
包含一些JQuery 来查找max和min rgb值的索引。
function saturation(i,v) { //i as in input, v as saturation value
var min = $.inArray(Math.min.apply(this, i), i), //returns the index of min, max and mid.
max = $.inArray(Math.max.apply(this, i), i),
mid = parseInt([0, 1, 2].filter(function (j) {return Array(min, max).indexOf(j) < 0;})),
r = (i[max] - i[mid]) / (i[mid] - i[min]), //ratio, because it is always constant,
//we use this to calc mid value
o = []; //o as in output
if (min !== max) {
o[max] = Math.round(i[max]);
o[min] = Math.round(i[max] * (1 - v));
o[mid] = Math.round(o[max] / (r + 1) * v + i[max] * (1 - v));
}
return o;
}
saturation([52,132,220], 0.5) //Array [ 110, 162, 220 ]
saturation([52,132,220], 0) //Array [ 220, 220, 220 ]
saturation([52,132,220], 1) //Array [ 0, 105, 220 ]
哇!我为自己感到骄傲!这里真的很晚了。
如果您在处理有关颜色的公式时遇到问题,我建议您绘制图表。
答案 1 :(得分:0)
使用中间值
的OP's answer知识new_mid = max / (r + 1) * sat + max * (1 - sat)
r = (max - mid) / (mid - min)
Can simplify...
new_mid = max / (((max - mid) / (mid - min)) + 1) * sat + max * (1 - sat)
= max * (sat / (((max - mid) / (mid - min)) + 1) + (1 - sat))
= max * ((1 - sat) + sat / (((max - mid) / (mid - min)) + ((mid - min) / (mid - min))))
= max * ((1 - sat) + sat / (((max - mid) + (mid - min)) / (mid - min)))
= max * ((1 - sat) + sat * (mid - min) / ((max - mid) + (mid - min)))
= max * ((1 - sat) + sat * (mid - min) / (max - min))
let
a = max - min
b = mid - min
=>
new_mid = max * ((1 - sat) + sat * b / a)
我重写了不使用 jQuery 的方法,减少了分割并接受了更多输入
// Inputs
// Array rgb colour data, s new hsl saturation
// Outputs
// Array rgb colour data
function saturation(rgb, s) {
var min = rgb.indexOf(Math.min.apply(null, rgb)), // index of min
max = rgb.indexOf(Math.max.apply(null, rgb)), // index of max
mid = [0, 1, 2].filter(function (i) {return i !== min && i !== max;})[0],
a = rgb[max] - rgb[min],
b = rgb[mid] - rgb[min],
x = rgb[max],
arr = [x, x, x];
if (min === max) {
min = 2; // both max = min = 0, => mid = 1, so set min = 2
a = 1; // also means a = b = 0, don't want division by 0 in `b / a`
}
arr[max] = x;
arr[min] = Math.round(x * (1 - s));
arr[mid] = Math.round(x * ((1 - s) + s * b / a));
return arr;
}
现在和以前一样,
saturation([52, 132, 220], 0.5); // [ 110, 162, 220 ]
saturation([52, 132, 220], 0); // [ 220, 220, 220 ]
saturation([52, 132, 220], 1); // [ 0, 105, 220 ]
但也适用于具有相等部分的值
saturation([80, 80, 80], 0.5); // [80, 40, 40] vs []
更改值更容易
// Inputs
// Array rgb colour data, v new hsl value
// Outputs
// Array rgb colour data
function nvalue(rgb, v) {
var x = Math.max.apply(null, rgb);
if (x === 0)
return [
Math.round(255 * v),
Math.round(255 * v),
Math.round(255 * v)
];
x = 255 * v / x;
return [
Math.round(rgb[0] * x),
Math.round(rgb[1] * x),
Math.round(rgb[2] * x)
];
}