昨天我遇到了一个需要减轻 UIColor 的情况,所以我创建了一个类别并添加了一个lighten
方法。我认为将值乘以颜色的每个分量是直截了当的,但我的绿色开始变黄,所以我知道它必须更复杂。
我想出的解决方案是从 sRGB 转换为线性,乘以颜色,然后再转换回来。这似乎有效,但我不确定它是否“正确”。我在文档中找不到任何说明 UIColor 在 sRGB 空间中的内容。我也不是色彩科学家,所以我对所涉及的数学只有初步的了解。
无论如何,这是我的代码,我要求进行一些同行评审,看看是否有人对修改 UIColors 有更好的理解。
CGFloat sRGB2Linear(CGFloat x){
CGFloat a = 0.055;
if(x <= 0.04045){
return x * (1.0 / 12.92);
}else{
return pow((x + a) * (1.0 / (1 + a)), 2.4);
}
}
CGFloat linear2sRGB(CGFloat x){
CGFloat a = 0.055;
if(x <= 0.0031308){
return x * 12.92;
}else{
return (1 + a) * pow(x, 1 / 2.4) - a;
}
}
- (UIColor *)lighten:(CGFloat)value{
const CGFloat *components = CGColorGetComponents([self CGColor]);
CGFloat newR = (sRGB2Linear(components[0])+1)*value;
CGFloat newG = (sRGB2Linear(components[1])+1)*value;
CGFloat newB = (sRGB2Linear(components[2])+1)*value;
newR = MAX(0, MIN(1, linear2sRGB(newR)));
newG = MAX(0, MIN(1, linear2sRGB(newG)));
newB = MAX(0, MIN(1, linear2sRGB(newB)));
return [UIColor colorWithRed:newR green:newG blue:newB alpha:components[3]];
}