TT.
TT.

Reputation: 1359

Calculate a color fade

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!

Upvotes: 12

Views: 18248

Answers (7)

hbk
hbk

Reputation: 11184

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

Upvotes: 0

Chris Dolphin
Chris Dolphin

Reputation: 1598

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

Upvotes: 4

nickf
nickf

Reputation: 546035

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.

Upvotes: 21

Tom
Tom

Reputation: 10819

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).

Upvotes: 5

Adam Davis
Adam Davis

Reputation: 93565

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

Upvotes: 11

Drew Hall
Drew Hall

Reputation: 29045

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.

Upvotes: 1

Kent Fredric
Kent Fredric

Reputation: 57354

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.

Upvotes: 1

Related Questions