我正在尝试编写一个函数来改变 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);
}
我知道你可以用 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 然后再转换回来之间,这似乎相当矫枉过正。
我可能最终会在应用程序中使用查找表或预先计算颜色,但我真的很好奇是否有一种方法可以使我的代码正常工作。谢谢!