I have written this function for the sole purpose to get a similar color either brighter or darker than any given color, depending on an average lightness/darkness. Essentially, I add up the R/G/B values and divide by 3, thus giving the average intensity of each color channel. Then, depending on that result, if it's less than half (darker) I lighten the color, and if it's more than half (lighter), I darken the color. The amount to lighten/darken depends on a given "difference" parameter (
The purpose and use of this function is in custom drawing controls to color themes, and shading colors based on other colors. If the color is dark, the tweaked color is a little bit lighter. If the color is light, the tweaked color is a little bit darker.
Do you see any shortcomings with my approach? Could I make this any better?
function IntRange(const Value, Min, Max: Integer): Integer; begin Result:= Value; if Result < Min then Result:= Min; if Result > Max then Result:= Max; end; function TweakColor(const AColor: TColor; const ADiff: Integer): TColor; var R, G, B: Byte; D: Integer; Dir: Integer; begin R:= GetRValue(AColor); G:= GetGValue(AColor); B:= GetBValue(AColor); D:= (R + G + B) div 3; //D = average difference of all 3 color channels if D >= (256 div 2) then begin //If average is a lighter color... Dir:= -ADiff; //Make the color darker end else begin //If average is a darker color... Dir:= ADiff; //Make the color lighter end; R:= IntRange(R + Dir, 0, 255); G:= IntRange(G + Dir, 0, 255); B:= IntRange(B + Dir, 0, 255); Result:= RGB(R, G, B); end;
Canvas.Font.Color:= TweakColor(Canvas.Font.Color, 50);