Я пытаюсь написать функцию для смещения оттенка цвета RGB. В частности, я использую его в приложении для iOS, но математика универсальна.
График ниже показывает, как значения R, G и B изменяются относительно оттенка.
![Graph of RGB values across hues](https://i.stack.imgur.com/D2bPL.png)
Глядя на это, кажется, что было бы относительно просто написать функцию для смещения оттенка без каких-либо неприятных преобразований в другой цветовой формат, который привел бы к большей ошибке (что могло бы стать проблемой, если продолжать применять небольшие сдвиги к цвет), и я подозреваю, что будет в вычислительном отношении дороже.
Вот что у меня есть, какие работы. Он отлично работает, если вы переходите от чистого желтого, голубого или пурпурного, но в некоторых местах он становится немного шатким.
Color4f ShiftHue(Color4f c, float d) {
if (d==0) {
return c;
}
while (d<0) {
d+=1;
}
d *= 3;
float original[] = {c.red, c.green, c.blue};
float returned[] = {c.red, c.green, c.blue};
// big shifts
for (int i=0; i<3; i++) {
returned[i] = original[(i+((int) d))%3];
}
d -= (float) ((int) d);
original[0] = returned[0];
original[1] = returned[1];
original[2] = returned[2];
float lower = MIN(MIN(c.red, c.green), c.blue);
float upper = MAX(MAX(c.red, c.green), c.blue);
float spread = upper - lower;
float shift = spread * d * 2;
// little shift
for (int i = 0; i < 3; ++i) {
// if middle value
if (original[(i+2)%3]==upper && original[(i+1)%3]==lower) {
returned[i] -= shift;
if (returned[i]<lower) {
returned[(i+1)%3] += lower - returned[i];
returned[i]=lower;
} else
if (returned[i]>upper) {
returned[(i+2)%3] -= returned[i] - upper;
returned[i]=upper;
}
break;
}
}
return Color4fMake(returned[0], returned[1], returned[2], c.alpha);
}
Я знаю, что вы можете сделать это с помощью UIColors и изменить цвет на что-то вроде этого:
CGFloat hue;
CGFloat sat;
CGFloat bri;
[[UIColor colorWithRed:parent.color.red green:parent.color.green blue:parent.color.blue alpha:1] getHue:&hue saturation:&sat brightness:&bri alpha:nil];
hue -= .03;
if (hue<0) {
hue+=1;
}
UIColor *tempColor = [UIColor colorWithHue:hue saturation:sat brightness:bri alpha:1];
const float* components= CGColorGetComponents(tempColor.CGColor);
color = Color4fMake(components[0], components[1], components[2], 1);
но я не в восторге от этого, так как он работает только в iOS 5, и между выделением ряда цветных объектов и преобразованием из RGB в HSB, а затем обратно это кажется довольно излишним.
Я мог бы в конечном итоге использовать справочную таблицу или предварительно рассчитать цвета в моем приложении, но мне действительно любопытно, есть ли способ заставить мой код работать. Спасибо!