Generating a series of colors between two colors

Given a start color and an end color, is it possible to algorithmically generate a range of colors between them? For example, given the light and dark shades of blue/gray at the start and end of the image below, how might I generate the intermediate shades?

enter image description here

One possible solution I am considering is to create a gradient from the two colors and then sample the color at equidistant points along that gradient. Is that likely to be the best approach?

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

Take a look at this answer. How to make a given color a bit darker or lighter?

Where you simply take the separated values of each RGB component and divide the values.

But we have one problem, there is not just one way to make a color transition.

enter image description here

The first aproach will give you the shortest route (1) but probably that route is not what you need.

This is also afected by the color model or logic. For example, in Lab* color model the Red and Green are complementary colors, so the short route on that model will be passing thru a neutral gray (3).

If you only need shades of a color, the other answer is a suitable one.

Solution 2

This is called color interpolation. It is what gradients do under the hood. You can do so using a variety of means and methods, and exactly how the results are interpolated depends on the method.

I commonly do this for web projects using JavaScript so that I can change colors dynamically, such as in this music visualizer. A JavaScript implementation that has a very straightforward method of linear interpolation using RGB, pulled from the example above, is as follows:

Live demo

// 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;
}

Which is used like so and returns an array of the interpolated colors:

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

You can also find PhotoShop (and likely other program) extensions for doing color interpolation.

However, you might want to check to make sure the method of interpolation is the same one that you desire, as you can use any function and color system to interpolate based on. For more about what I mean by that, see Rafael’s answer. Also, here’s one tool that generates gradients using a few different methods that illustrates the difference.

Solution 3

Use a blend in Illustrator in either RGB or CMYK:

  • create 2 shapes each with the start and end color (one gray and one black in this example, but choose whatever you need)
  • go to Object → Blend → Blend Options and type in how many Specified steps you need in between (20 in my example below)
  • select your two objects and choose Object → Blend → Make. This will generate the blend which you can then transform to individual objects via Object → Expand. Then you can see each intermediate object with it’s own color code.

Generating a series of colors between two colors

Solution 4

This is an addition to the other answers.

When you interpolate colors in sRGB you have to consider that the RGB values are not linear in light intensity but linear in human perceived light intensity. This makes saving values easier, but for various color operations it is necessary to go to linear color space.

The human perception of light intensity is according to a power law, so with

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

can be used to transform between the two. This uses a gamma value of 2.2 which is the value for sRGB. For further information on this see this Wikipedia article.

A detailed analysis of this problem and examples of wrong implementations can be found here. One of which is a color gradient using linear and sRGB interpolation.

Solution 5

Photoshop’s gradient (or equivalently “Blend” in Ai) is already presented as a way to get a linear color transition between the starting and ending colors. How do we get something nonlinear (a curved transition path) without programming some scripting code?

One solution is to modify the gradient transition path by adjustment layers or blending modes or both. This really produces a continuous transform from the start color to the end color, if the modifying layers have a layer mask that is continuous and makes the affection = Zero at the start and in the end.

Here is a quite complex twist. Layer “Target alone” has the gradient and layer “Modifier” produces a continuous color shift by blending mode “Color” To make all twisty, the modifier itself is a gradient.

More twist is generated by an adjustment layer “Curves” that add contrast. It has the same layer mask as the Modifier, but that’s not obligatory. Any mask is ok, if it’s continuous and black at the start and in the end.

There exists some uncontinuous blending modes and curves that cause an abrupt jump. One of those is “Hue”. Another possiblity to spoil the effect is “no change”, a visible constant color area caused by clipping to all zero or all 255. I have not tested nor calculated, how much it in practice helps to use 48 bit/pixel RGB mode. Maybe not at all, because we still have only 24 bits/pixel onscreen.

Transition

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply