Как сделать стандартные цвета в Delphi светлее или темнее

В данной статье хотелось бы показать принцип получения из обычного цвета более тёмный или более светлый. А так же рассмотрим, как этот принцип реализовани в программном коде.
Итак, немного теории:
Каждый из трёх основных цветов (Красный, Зелёный, Синий) могут иметь значение от 0 до 255, соответственно скомбинировав их мы можем получить 16,777,216 возможных цветов. Визуально это можно представить как три оси куба, в котором направления x, y и z отвечают за цвета красный, зелёный и синий. В сочетании эти направления дают точку в кубе, представляющую один цвет из 16 миллионов. Точка куба, в которой значение равняется 0 (0,0,0) соответствует чёрному цвету, значение (255, 255, 255) - белому цвету, (255, 0, 0) - чисто красному, и т.д.
Если визуально провести линию между каким-либо цветом (r, g, b) и белым цветом (255, 255, 255), то получится, что на этой линии будут лежать все значения данного цвета (r, g, b). Если мы будем двигаться по линии в сторону белого цвета, то яркость будет увеличиваться до тех пор пока не получим чисто белый цвет.
То же самое можно сделать и для уменьшения яркости цвета. Достаточно провести линию из цвета (r, g, b) в чёрный (0, 0, 0). То есть при движении по линии к чёрному цвету мы будем уменьшать яркость до тех пор, пока не получим чёрный цвет.
* Функция "Darker" возвращает новое значение цвета, которое будет на сколько-то процентов темнее. Естественно, что при 100% мы получим чёрный цвет.
* Функция "Lighter" возвращает цвет, который светлее на сколько-то процентов исходного. 100% - белый цвет.
Функции Darker и Lighter требуют 2 параметра и используются примерно так:
Panel1.Color := Darker(clBlue, 20);
Получается панель цветов, которая на 20% темнее обычного синего цвета.
Теперь давайте посмотрим, как выглядят внутри наши функции:
function Darker(Color: TColor; Percent: Byte): TColor;
var
 r, g, b: Byte;
begin
 Color := ColorToRGB(Color);
 r := GetRValue(Color);
 g := GetGValue(Color);
 b := GetBValue(Color);
 r := r - MulDiv(r, Percent, 100); // процент% уменьшения яркости
 g := g - MulDiv(g, Percent, 100);
 b := b - MulDiv(b, Percent, 100);
 Result := RGB(r, g, b);
end;
function Lighter(Color: TColor; Percent: Byte): TColor;
var
 r, g, b: Byte;
begin
 Color := ColorToRGB(Color);
 r := GetRValue(Color);
 g := GetGValue(Color);
 b := GetBValue(Color);
 r := r + MulDiv(255 - r, Percent, 100); // процент% увеличения яркости
 g := g + MulDiv(255 - g, Percent, 100);
 b := b + MulDiv(255 - b, Percent, 100);
 Result := RGB(r, g, b);
end;
Так же я добавил некоторые функции, в которых уже добавлены стандартные значения процентов. Это для тех, кому некогда задумываться над процентами :)
Panel1.Color := Light(clBlue);
Panel1.Color := SlightlyDark(clRed);
Panel1.Color := VeryLight(clMagenta);
и т.д..
function SlightlyDark(Color: TColor): TColor;
begin
 Result := Darker(Color, 25);
end;
function Dark(Color: TColor): TColor;
begin
 Result := Darker(Color, 50);
end;
function VeryDark(Color: TColor): TColor;
begin
 Result := Darker(Color, 75);
end;
function SlightlyLight(Color: TColor): TColor;
begin
 Result := Lighter(Color, 25);
end;
function Light(Color: TColor): TColor;
begin
 Result := Lighter(Color, 50);
end;
function VeryLight(Color: TColor): TColor;
begin
 Result := Lighter(Color, 75);
end;
Author: Den Bedard
Source: http://forum.sources.ru
ID: 03672
== См. также ==
* Как получить более светлый или более тёмный цвет?
Category:Графика
Category:Цвета и палитры