Наиболее точный способ сделать это - преобразовать значение RGB в HSL или HSV (оттенок, насыщенность, яркость / яркость), а затем отрегулировать значения насыщенности и / или яркости / яркости (оставив только оттенок). Затем преобразовать обратно в RGB.
Когда вы пытаетесь сделать математику непосредственно для значений RGB, вы, как правило, получаете изменения оттенка.
Насыщенность - это насколько чистый цвет, значение 0.0 - серый, а значение 1.0 - чистый цвет.
Яркость / Яркость - это не одно и то же, но они похожи. Они оба используются для перемещения значения в сторону черного или белого.
Поэтому, когда вы говорите «светлее», вы, вероятно, имеете в виду больше для белого, но вы также можете означать больше для серого (ненасыщенного). Или возможно оба.
После того как значение RGB преобразовано в Оттенок, Насыщенность и Яркость, вы просто умножаете яркость на некоторое число> 1, чтобы сделать его ярче, или Насыщенность на некоторое значение <1, чтобы сделать его серее. затем преобразовать обратно в RGB. </p>
Я не знаю сценарий действия, но вот псевдокод в стиле C для RGB-> HSB и HSB-> RGB.
RGB в HSB
unsigned int RGB;
double red = ((RGB >> 16) & 0xFF) / 255.0; // red value between 0.0 and 1.0
double green = ((RGB >> 8) & 0xFF) / 255.0;
double blue = ((RGB) & 0xFF) / 255.0);
double dmax = max(max(red, green) blue);
double dmin = min(min(red, green) blue);
double range = dmax - dmin;
double brite = dmax;
double sat = 0.0;
double hue = 0.0; // hue is always 0 when sat is 0
if (dmax != 0.0) sat = range / dmax;
if (sat != 0.0)
{
if (red == dmax)
hue = (green - blue) / range;
else if (green = dmax)
hue = 2.0 + (blue - red) / range;
else if (blue == dmax)
hue = 4.0 + (green - red) / range;
// it is conventional to convert hue to a value between 0 and 360.0 (a color circle)
hue = hue * 60;
if (hue < 0.0)
hue = hue + 360.0;
}
// result is now in hue, sat, & brite variables
от HSB до RGB
double hue, sat, brite; // these are inputs
double red, green, blue;
if (sat == 0.0)
{
red = brite;
green = brite;
blue = brite;
}
else
{
if (hue == 360.0)
hue = 0;
int slice = (int)(hue / 60.0);
double hue_frac = (hue / 60.0) - slice;
double aa = brite * (1.0 - sat);
double bb = brite * (1.0 - sat * hue_frac);
double cc = brite * (1.0 - sat * (1.0 - hue_frac));
switch (slice)
{
case 0: red = brite; green = cc; blue = aa; break;
case 1: red = bb; green = brite; blue = aa; break;
case 2: red = aa; green = brite; blue = cc; break;
case 3: red = aa; green = bb; blue = brite; break;
case 4: red = cc; green = aa; blue = brite; break;
case 5: red = brite; green = aa; blue = bb; break;
default: red = 0.0; green = 0.0; blue = 0.0; break;
}
}
int ir = (int)(red * 255);
int ig = (int)(green * 255);
int ib = (int)(blue * 255);
// this is the result.
unsigned int RGB = (ir << 16) | (ig << 8) | ib;