在两种颜色之间生成一系列颜色

平面设计 颜色 颜色理论
2022-01-25 15:20:00

给定开始颜色和结束颜色,是否可以通过算法在它们之间生成一系列颜色?例如,给定下图开始和结束处的蓝色/灰色的浅色和深色阴影,我如何生成中间阴影?

在此处输入图像描述

我正在考虑的一种可能的解决方案是从两种颜色创建一个渐变,然后在沿该渐变的等距点对颜色进行采样。这可能是最好的方法吗?

4个回答

看看这个答案。如何使给定的颜色更深或更浅?

您只需获取每个 RGB 组件的分离值并将这些值相除。

但是我们有一个问题,进行颜色转换的方法不止一种。

在此处输入图像描述

第一种方法会给你最短的路线(1),但这条路线可能不是你需要的。

这也受颜色模型或逻辑的影响。例如,在 Lab* 颜色模型中,红色和绿色是互补色,因此该模型上的短路径将通过中性灰色 (3)。

如果您只需要一种颜色的深浅,另一个答案是合适的。

这称为颜色插值这就是渐变在幕后所做的。您可以使用多种方式和方法来完成此操作,而结果的准确插值方式取决于方法。

我通常为使用 JavaScript 的 Web 项目执行此操作,以便我可以动态更改颜色,例如在这个音乐可视化器中。从上面的示例中提取的具有非常简单的使用 RGB 的线性插值方法的 JavaScript 实现如下:

现场演示

// Returns a single rgb color interpolation between given rgb color
// based on the factor given; via https://codepen.io/njmcode/pen/axoyD?editors=0010
function interpolateColor(color1, color2, factor) {
    if (arguments.length < 3) { 
        factor = 0.5; 
    }
    var result = color1.slice();
    for (var i = 0; i < 3; i++) {
        result[i] = Math.round(result[i] + factor * (color2[i] - color1[i]));
    }
    return result;
};
// My function to interpolate between two colors completely, returning an array
function interpolateColors(color1, color2, steps) {
    var stepFactor = 1 / (steps - 1),
        interpolatedColorArray = [];

    color1 = color1.match(/\d+/g).map(Number);
    color2 = color2.match(/\d+/g).map(Number);

    for(var i = 0; i < steps; i++) {
        interpolatedColorArray.push(interpolateColor(color1, color2, stepFactor * i));
    }

    return interpolatedColorArray;
}

像这样使用它并返回一个插值颜色的数组:

var colorArray = interpolateColors("rgb(94, 79, 162)", "rgb(247, 148, 89)", 5);

您还可以找到用于进行颜色插值的 PhotoShop(以及可能的其他程序)扩展。

但是,您可能需要检查以确保插值方法与您想要的方法相同,因为您可以使用任何函数和颜色系统进行插值。有关我的意思的更多信息,请参阅Rafael 的回答此外,这是一个使用几种不同方法生成渐变的工具,可以说明差异。

在 RGB 或 CMYK 中使用 Illustrator 中的混合:

  • 创建 2 个形状,每个形状都具有开始颜色和结束颜色(在此示例中为一个灰色和一个黑色,但选择您需要的任何颜色)
  • 转到Object → Blend → Blend Options并输入Specified steps您需要的数量(在下面的示例中为 20)
  • 选择你的两个对象并选择Object → Blend → Make这将生成混合,然后您可以通过 将其转换为单个对象Object → Expand然后你可以看到每个中间对象都有自己的颜色代码。

混合

这是对其他答案的补充。

当您在 sRGB 中插入颜色时,您必须考虑 RGB 值在光强度方面不是线性的,而是在人类感知的光强度方面是线性的。这使得保存值更容易,但对于各种颜色操作,必须转到线性颜色空间。

人类对光强度的感知是根据幂律的,因此

linear = sRGB^2.2
sRGB = linear^(1/2.2)

可用于两者之间的转换。这使用 2.2 的伽玛值,这是 sRGB 的值。有关这方面的更多信息,请参阅Wikipedia 文章。

可以在此处找到对此问题的详细分析和错误实现的示例。其中之一是使用线性和 sRGB 插值的颜色渐变。