昨天我遇到了需要减轻UIColor的情况,因此我创建了一个类别并添加了lighten方法。我认为直接将值乘以颜色的每个分量会很简单,但是我的绿色开始变成黄色,所以我知道它必须更复杂。

我想出的解决方案是将sRGB转换为Linear,将颜色相乘,然后再转换回去。这似乎可行,但我不确定是否“正确”。我在文档中找不到任何说明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]];
}

最佳答案

这是我的iOS5 +解决方案,可轻松进行相对亮度更改(多合一变暗):

+ (UIColor*)changeBrightness:(UIColor*)color amount:(CGFloat)amount
{

    CGFloat hue, saturation, brightness, alpha;
    if ([color getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha]) {
        brightness += (amount-1.0);
        brightness = MAX(MIN(brightness, 1.0), 0.0);
        return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:alpha];
    }

    CGFloat white;
    if ([color getWhite:&white alpha:&alpha]) {
        white += (amount-1.0);
        white = MAX(MIN(white, 1.0), 0.0);
        return [UIColor colorWithWhite:white alpha:alpha];
    }

    return nil;
}

它的调用方式如下:
[self changeBrightness:someUiColor amount:1.1]

使用1.1将增加10%的亮度; 0.9将使亮度降低10%。请注意,相对于纯白色,10%是相对的(即10%总是使亮度增加0.1。)这是预期的行为,如果您想要增加百分比以使颜色始终变暗或变暗而不管其初始亮度如何。

10-08 18:49