在两种颜色之间的渐变上计算给定点的颜色?

45

所以,这基本上是我想要编写的方法(使用Objective-C/Cocoa,使用UIColors,但我只对底层的数学感兴趣):

所以,这就是我想要编写的方法(使用Objective-C/Cocoa,利用UIColors,但我真正关心的是底层的数学计算)。
+ (UIColor *)colorBetweenColor:(UIColor *)startColor andColor:(UIColor *)endColor atLocation:(CGFloat)location;

举例说明,假设我有两种颜色:纯红和纯蓝。如果在两者之间有一个线性渐变,我想计算出那个渐变过程中33%位置的颜色: Example
如果我像这样调用我的方法:

UIColor *resultingColor = [UIColor colorBetweenColor:[UIColor redColor] andColor:[UIColor blueColor] atLocation:0.33f];

我会在'B'处得到混合后的颜色,同样地,传递0.0f作为位置将返回颜色'A',而1.0f将返回颜色'C'。

所以我的问题基本上是,如何混合两个颜色的RGB值,并确定它们之间特定“位置”的颜色?


1
你可能想查看这个答案 - andreamazz
3个回答

76

你只需简单地线性插值红色、绿色和蓝色通道,方法如下:

double resultRed = color1.red + percent * (color2.red - color1.red);
double resultGreen = color1.green + percent * (color2.green - color1.green);
double resultBlue = color1.blue + percent * (color2.blue - color1.blue);

其中percent是一个介于0到1之间的值(在您的第一个方法原型中的location参数)。


1
@LudovicLandry 能否详细说明一下?您可以在任何颜色空间中进行线性插值,但结果可能并不总是令人满意或符合您的期望。 (实际上,即使在RGB中,您经常会经过灰色,这有时也是不希望的。)以上方法在哪些颜色空间中无法使用? - user1118321
例如,这将无法在[UIColor whiteColor]上工作,因为它不是RGB颜色。请参见https://dev59.com/R2445IYBdhLWcg3wydFk。 - Ludovic Landry
2
@LudovicLandry - 噢,我明白你的意思了。是的,你需要将命名颜色转换成其他的颜色空间(RGB、HSV、CMYK等)。但一旦它们在一个可以进行数学计算的颜色空间中,线性插值就可以正常工作了。 - user1118321
谢谢,我感觉有点傻,没有意识到这一点。非常感谢。 - Gregorio Freidin

2

我知道这不是一个纯粹的JavaScript问题,但我也曾为同样的概念苦苦挣扎,所以我想制作一个演示来可视化接受的答案。

运行下面的代码并移动滑块。

var sample=document.querySelector("#sample")
var range=document.querySelector("#range")

// rgb(255,0,0)
var color1_red=255
var color1_green=0
var color1_blue=0

// rgb(0,0,255)
var color2_red=0
var color2_green=0
var color2_blue=255


document.querySelector("#range").addEventListener("input",(event)=>{
 let percent= range.value/100.0
 
 let resultRed = color1_red + percent * (color2_red - color1_red);
 let resultGreen = color1_green + percent * (color2_green - color1_green);
 let resultBlue = color1_blue + percent * (color2_blue - color1_blue);
 
 sample.style.backgroundColor=`rgb(${resultRed},${resultGreen},${resultBlue})`
})
#sample{
  height:10rem;
  width:10rem;
}

#range{
  width:10rem
}

#grad{
  width:10rem;
  height:2rem;
  background-image: linear-gradient(to right, red , blue);
}
<div id="grad"></div>
<input type="range" min="1" max="100" value="0" id="range">

<div id="sample" style="background-color:rgb(255,0,0);"></div>

希望这能在某种程度上有所帮助 :)

0

RGB颜色空间就像一个圆。最高饱和度在外边缘,中间是灰色。从一种颜色到另一种颜色,最好沿着同一半径(圆)从中心开始进行;这样饱和度和值保持不变。在这种情况下,色调呈线性变化。您不会跨越比左右颜色更多的灰色区域。

您可以从内环移动到外环,只需线性地增加(或减少)饱和度即可。

请参见此处的颜色圆(例如在paint.net中尝试)

苹果(iOS)的目标类允许您使用其他光谱。


9
RGB不像一个圆,它是一个立方体。类似HSV或HSB的空间以角度或弧度形成色相圆。 - Henrik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接