Reputation: 1359
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
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
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
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
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
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
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
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