我正在尝试编写一个函数来改变RGB颜色的色调。具体来说,我将在iOS应用程序中使用它,但数学原理是通用的。
下面的图显示了R、G和B值相对于色调的变化。
从这个图可以看出,编写一个函数来改变色调似乎应该是相对简单的,而不必进行任何可能会引入更多误差的其他颜色格式的转换(如果继续对颜色应用小的变化,则可能会成为问题),我认为这种方法也更加计算密集。
这是我到目前为止的代码,它有点有效但并不完美。如果你需要改变纯黄色、青色或洋红色的颜色,那么它是完美的,但在其他一些地方会有一些小偏差。
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);
}
我知道你可以使用UIColor,通过类似以下的方式改变色调:
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再转回来,似乎有些过度了。
也许我最终会使用查找表或在我的应用程序中预先计算颜色,但我真的很想知道是否有办法使我的代码工作。谢谢!