2012-10-03 8 views
7

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]]; 
} 

Odpowiedz

4

Możesz pracować z odcieniem, nasyceniem i jasnością.

Get starych wartości używając

- (BOOL)getHue:(CGFloat *)hue saturation:(CGFloat *)saturation brightness:(CGFloat *)brightness alpha:(CGFloat *)alpha 

następnie ustawić jasność i skonstruować nowy kolor:

- (UIColor *)initWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha 

Należy pamiętać, że trzeba przekazać wskaźniki do pierwszej funkcji.

+0

Jeśli kolor ma skalę szarości, nie działa. – ozgur

24

To jest moje rozwiązanie iOS5 + łatwo dokonać względnych zmian jasności (rozjaśnienia i przyciemnienia all-in-one):

+ (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; 
} 

Jest wywoływany tak:

[self changeBrightness:someUiColor amount:1.1] 

Korzystanie 1.1 zwiększy jasność o 10%; 0.9 spowoduje zmniejszenie jasności o 10%. Zauważ, że 10% jest w stosunku do czystej bieli (tj. 10% jest zawsze wzrostem jasności .1). Jest to oczekiwane zachowanie, jeśli chcesz zwiększyć procent, aby rozjaśnić lub przyciemnić kolory konsekwentnie, niezależnie od ich początkowej jasności.

+0

Doskonały kod. Dziękuję za udostępnienie. –

0

Ulepszyłem metodę Anka, aby umożliwić modyfikację nasycenia i odcienia.

Dane wejściowe są traktowane jako procent, więc b z 1,0 równa się 100% (bez zmian). Aby osłabić jasność o 30%, ustaw b na 0.7.

+ (UIColor*)changeColor:(UIColor*)color brightness:(CGFloat)b saturation:(CGFloat)s hue:(CGFloat)h 
{ 

    CGFloat hue, saturation, brightness, alpha; 
    if ([color getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha]) { 
     brightness *= b; 
     brightness = MAX(MIN(brightness, 1.0), 0.0); 
     saturation *= s; 
     saturation = MAX(MIN(saturation, 1.0), 0.0); 
     hue *= h; 
     hue = MAX(MIN(hue, 1.0), 0.0); 
     return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:alpha]; 
    } 

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

    return nil; 
} 
0

spróbować

- (UIColor *)mixColorWithWhiteAndAlpha:(CGFloat)alpha { 
    CGFloat r, g, b, a; 
    if ([self getRed:&r green:&g blue:&b alpha:&a]) 
     return [UIColor colorWithRed:r + (1 -r) * alpha 
           green:g + (1 -g) * alpha 
           blue:b + (1 -b) * alpha 
           alpha:a]; 
    return nil; 
} 

powinien powrócić mieszany biały kolor z kolorem

więc można ustawić alfa 0,2 i myślę, że będzie ok

0

odpowiedź KOF w Swift :

extension UIColor { 
    public func changeBrightness(b: CGFloat, saturation s: CGFloat = 1.0, hue h: CGFloat = 1.0) -> UIColor? { 
     var hue : CGFloat = 0.0 
     var saturation : CGFloat = 0.0 
     var brightness : CGFloat = 0.0 
     var alpha : CGFloat = 0.0 

     if self.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) { 
      brightness *= b 
      brightness = max(min(brightness, 1.0), 0.0) 
      saturation *= s 
      saturation = max(min(saturation, 1.0), 0.0) 
      hue *= h 
      hue = max(min(hue, 1.0), 0.0) 

      return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha) 
     } 

     var white: CGFloat = 0.0 
     if self.getWhite(&white, alpha: &alpha) { 
      white += (b - 1.0) 
      white = max(min(b, 1.0), 0.0) 

      return UIColor(white: white, alpha: alpha) 
     } 

     return nil 
    } 
} 
0
- (UIColor *)changeBrightnessToPercentage:(CGFloat)percentage { 
    CGFloat hue, saturation, brightness, alpha; 
    if ([self getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha]) { 
     brightness += (percentage - 1.0); 
     brightness = MAX(MIN(brightness, 1.0), 0.0); 
     return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:alpha]; 
    } 

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

    return nil; 
} 

== 1.0 to dostarczony kolor,> 1,0 jest lżejszy, a < 1,0 jest ciemniejszy.

Powiązane problemy