Question

Given two colors and n steps, how can one calculate n colors including the two given colors that create a fade effect?

If possible pseudo-code is preferred but this will probably be implemented in Java.

Thanks!

Was it helpful?

Solution

Divide each colour into its RGB components and then calculate the individual steps required.

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

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

Obviously extend that for green and blue.

OTHER TIPS

There are two good related questions you should also review:

Please note that you're often better off doing this in the HSV color space rather than RGB - it generates more pleasing colors to the human eye (lower chance of clashing or negative optical properties).

Good luck!

-Adam

If you want a blend that looks anything like most color picker GUI widgets, you really want to translate to HSL or HSV. From there, you're probably fine with linear interpolation in each dimension.

Trying to do any interpolations directly in RGB colorspace is a bad idea. It's way too nonlinear (and no, gamma correction won't help in this case).

For those looking for something they can copy and paste. Made a quick function for RGB colors. Returns a single color that is the amount of ratio closer to rgbColor2.

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 + ')';
}

The quesiton is what transformation do you want to occur? If you transpose into the HSV colourspace and given

FF0000 and 00FF00

It will transition from red through yellow to green.

However, if you define "black" or some other shade as being the mid-point of the blend, you have to shade to that colour first ff0000->000000->00ff00 or via white : ff0000 -> ffffff -> 00ff00.

Transforming via HSV however can be fun because you have to use a bit of trig to map the circular map into the vector components.

The easiest thing to do is linear interpolation between the color components (see nickf's response). Just be aware that the eye is highly nonlinear, so it won't necessarily look you're making even steps. Some color spaces attempt to address this (CIE maybe?), so you might want to transform into another color space first, interpolate, then transform back to RGB or whatever you're using.

How about this answer

- (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];
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top