Wpadłem wczoraj w sytuację, w której potrzebowałem rozjaśnić UIColor, więc stworzyłem kategorię i dodałem metodę lighten
. Sądziłem, że proste byłoby pomnożenie wartości przez każdy składnik koloru, ale moje zielenie zaczęły żółknąć, więc wiedziałem, że to musi być bardziej skomplikowane.Rozjaśnianie UIColor
Rozwiązaniem, które wymyśliłem, było przekonwertowanie z sRGB na liniowy, pomnożenie koloru, a następnie konwersja z powrotem. To wydaje się działać, ale nie jestem pewien, czy jest "poprawny". Nie mogłem znaleźć niczego w dokumentach, które stwierdzały, że UIColor był w przestrzeni sRGB. Nie jestem też naukowcem zajmującym się kolorystyką, więc mam tylko podstawową wiedzę na temat matematyki.
W każdym razie tutaj jest mój kod, proszę o sprawdzenie i sprawdź, czy ktoś lepiej rozumie modyfikowanie 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]];
}
Jeśli kolor ma skalę szarości, nie działa. – ozgur