计算颜色渐变

12

给定两个颜色和 n 步骤,如何计算出 n 种颜色,包括这两种给定的颜色,以产生渐变效果?

如果可能,请提供伪代码,但这可能会在 Java 中实现。

谢谢!

7个回答

21

将每种颜色分解为其RGB组件,然后计算所需的各个步骤。

oldRed = 120;
newRed = 200;
steps = 10;
redStepAmount = (newRed - oldRed) / steps;

currentRed = oldRed;
for (i = 0; i < steps; i++) {
   currentRed += redStepAmount;
}

显然可以将其扩展到绿色和蓝色。


5
代码中展示的内容永远不会到达新的红色值,这既是因为整数截断也是因为一个偏移量错误。更好的方法是重构代码,使用如下形式:currentRed = oldRed + ((i * (newRed - oldRed)) / (steps - 1),这样就可以避免这些问题。 - Mark Ransom
1
是的,当我写这个时,我也在考虑这个问题 - 但有几种方法可以解决,我想留一个练习给实现者 :-) - nickf

11

5
如果你想要一个看起来与大多数颜色拾取器GUI小部件类似的混合物,你确实需要将其转换为HSL或HSV。从那里开始,你可能只需要在每个维度上进行线性插值就可以了。
试图直接在RGB颜色空间中进行任何插值都是不明智的。这种方法太不线性化了(不,伽马校正在这种情况下没有帮助)。

我不太同意。有很多操作在其他颜色空间中运行得更好,但是在已知端点之间进行插值不是其中之一。 - Mark Ransom
我认为对于许多情况,基本的线性RGB转换是令人满意的,例如:我的文本框是红色的,当它被正确填充时,我希望它能漂亮地渐变为绿色。这一切在不到一秒钟内完成,已经足够了。 - nickf
@nickf - 如果这是一个时间效应,你比空间效应有更多的灵活性。@mark - 在HSV中插值有什么问题吗?我用它取得了相当大的成功。 - Tom

4

对于那些希望复制粘贴的人,我编写了一个快速的RGB颜色函数。它返回一种颜色,该颜色接近于 rgbColor2,并且其数量是 ratio 的比例。

function fadeToColor(rgbColor1, rgbColor2, ratio) {
    var color1 = rgbColor1.substring(4, rgbColor1.length - 1).split(','),
        color2 = rgbColor2.substring(4, rgbColor2.length - 1).split(','),
        difference,
        newColor = [];

    for (var i = 0; i < color1.length; i++) {
        difference = color2[i] - color1[i];
        newColor.push(Math.floor(parseInt(color1[i], 10) + difference * ratio));
    }

    return 'rgb(' + newColor + ')';
}

1
问题是您想要进行什么转换?如果您以HSV颜色空间为基础进行转换,并给出FF0000和00FF00,则它将从红色逐渐过渡到黄色再到绿色。
然而,如果您定义“黑色”或其他某种阴影为混合的中点,则必须先将颜色阴影到该颜色:ff0000-> 000000-> 00ff00,或通过白色:ff0000-> ffffff-> 00ff00。
通过HSV变换可能很有趣,因为您需要使用一些三角函数将环形图映射到向量分量中。

1
最简单的方法是在颜色分量之间进行线性插值(参见nickf的回答)。 请注意,眼睛高度非线性,因此它不一定看起来像您正在进行均匀的步骤。 一些颜色空间尝试解决这个问题(CIE可能?),因此您可能需要先转换为另一个颜色空间,然后进行插值,最后再转换回RGB或您正在使用的任何其他格式。

应用于颜色值的伽马将有助于抵消非线性,因此转换到另一个颜色空间可能过度。 - Mark Ransom

0

这个答案怎么样

- (UIColor *)colorFromColor:(UIColor *)fromColor toColor:(UIColor *)toColor percent:(float)percent
{
    float dec = percent / 100.f;
    CGFloat fRed, fBlue, fGreen, fAlpha;
    CGFloat tRed, tBlue, tGreen, tAlpha;
    CGFloat red, green, blue, alpha;

    if(CGColorGetNumberOfComponents(fromColor.CGColor) == 2) {
        [fromColor getWhite:&fRed alpha:&fAlpha];
        fGreen = fRed;
        fBlue = fRed;
    }
    else {
        [fromColor getRed:&fRed green:&fGreen blue:&fBlue alpha:&fAlpha];
    }
    if(CGColorGetNumberOfComponents(toColor.CGColor) == 2) {
        [toColor getWhite:&tRed alpha:&tAlpha];
        tGreen = tRed;
        tBlue = tRed;
    }
    else {
        [toColor getRed:&tRed green:&tGreen blue:&tBlue alpha:&tAlpha];
    }

    red = (dec * (tRed - fRed)) + fRed;
    green = (dec * (tGreen - fGreen)) + fGreen;
    blue = (dec * (tBlue - fBlue)) + fBlue;
    alpha = (dec * (tAlpha - fAlpha)) + fAlpha;

    return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
}

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