2008-11-26 7 views
9

Gegeben zwei Farben und n Schritte, wie kann man n Farben einschließlich der zwei gegebenen Farben berechnen, die einen Verblassungseffekt verursachen?Berechne ein Farbverblassen

Wenn möglich, wird Pseudo-Code bevorzugt, aber dies wird wahrscheinlich in Java implementiert.

Danke!

Antwort

21

Teilen Sie jede Farbe in ihre RGB-Komponenten auf und berechnen Sie dann die einzelnen erforderlichen Schritte.

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

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

Offensichtlich erweitern, dass für grün und blau.

+5

den Code als newRed nie erreichen gezeigt wird, sowohl wegen der Integer-Abschneiden und ein Off-by-one Fehler. Besser zu restrukturieren als currentRed = oldRed + ((* (newRed - oldRed))/(steps - 1) –

+1

ja ich dachte daran, als ich es schrieb - aber es gibt ein paar Möglichkeiten, und ich dachte ich würde eine Übung für den Implementierer hinterlassen :-) – nickf

1

Die Frage ist, welche Transformation möchten Sie auftreten? Wenn Sie den HSV-Farbraum umsetzen in und

FF0000 gegeben und 00FF00

Es wird grün bis gelb von Rot übergehen.

Wenn Sie jedoch "schwarz" oder einen anderen Farbton als Mittelpunkt der Mischung definieren, müssen Sie zuerst auf diese Farbe schattieren: ff0000-> 000000-> 00ff00 oder weiß: ff0000 -> ffffff - > 00ff00.

Das Umwandeln über HSV kann jedoch Spaß machen, weil Sie ein bisschen trig verwenden müssen, um die kreisförmige Karte den Vektorkomponenten zuzuordnen.

1

Am einfachsten ist eine lineare Interpolation zwischen den Farbkomponenten (siehe Antwort von Nickf). Seien Sie sich bewusst, dass das Auge stark nichtlinear ist, so dass es nicht unbedingt aussieht, dass Sie gerade Schritte machen. Einige Farbräume versuchen, dies zu beheben (CIE vielleicht?), Also möchten Sie vielleicht zuerst in einen anderen Farbraum transformieren, interpolieren und dann zurück in RGB oder was auch immer Sie verwenden.

+0

Das Gamma, das auf Farbwerte angewendet wird, hilft, der Nichtlinearität entgegenzuwirken, also ist die Umwandlung in einen anderen Farbraum wahrscheinlich übertrieben. –

4

Wenn Sie eine Mischung, die etwas wollen, wie die meisten Farbauswahl GUI-Widgets aussieht, wollen Sie wirklich HSL oder HSV zu übersetzen. Von da an ist es wahrscheinlich in jeder Dimension linear interpoliert.

Versuchen alle Interpolationen direkt im RGB-Farbraum ist eine schlechte Idee. Es ist viel zu nichtlinear (und nein, Gammakorrektur wird in diesem Fall nicht helfen).

+0

Ich bitte um Unterschiede. Es gibt viele Operationen, die in anderen Farbräumen besser funktionieren, aber die Interpolation zwischen zwei bekannten Endpunkten gehört nicht dazu. –

+0

Ich denke, dass eine grundlegende lineare RGB-Transformation für viele Situationen zufriedenstellend ist, zB: mein Textfeld ist rot und ich möchte, dass es schön grün wird, wenn es richtig ausgefüllt wurde. Alles geschieht in weniger als einer Sekunde und ist ausreichend. – nickf

+0

@nickf - Wahr, wenn es ein temporaler Effekt ist, hast du viel mehr Spielraum als ein räumlicher Effekt. @mark - Was ist das Problem mit der Interpolation in HSV? Ich hatte ziemlich viel Erfolg damit. – Tom

4

Für diejenigen, die etwas suchen, können sie kopieren und einfügen. Hat eine schnelle Funktion für RGB-Farben gemacht. Gibt eine einzelne Farbe zurück, die ratio näher an rgbColor2 ist.

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

Wie wäre es 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]; 
}