151 votes

Obtenir une couleur légèrement plus claire et plus foncée avec UIColor

Je souhaitais pouvoir transformer n'importe quelle UIColor en un dégradé. J'ai l'intention de le faire en utilisant Core Graphics pour dessiner un dégradé. Ce que j'essaie de faire est d'obtenir une couleur, disons :

[UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0];

et obtenir une UIColor qui est quelques nuances plus foncées et quelques nuances plus claires. Quelqu'un sait-il comment procéder ? Merci.

1 votes

Le terme "gradient" implique qu'une partie de votre image sera une nuance de la couleur tandis qu'une autre partie sera une nuance plus sombre ou plus claire. Est-ce une autre façon de définir ce que vous voulez faire ?

2 votes

Jetez un coup d'œil à cette bibliothèque github.com/yannickl/DynamicColor

0 votes

Swift utilisant la teinte, la saturation et la luminosité stackoverflow.com/a/30012117/2303865

284voto

- (UIColor *)lighterColorForColor:(UIColor *)c
{
    CGFloat r, g, b, a;
    if ([c getRed:&r green:&g blue:&b alpha:&a])
        return [UIColor colorWithRed:MIN(r + 0.2, 1.0)
                               green:MIN(g + 0.2, 1.0)
                                blue:MIN(b + 0.2, 1.0)
                               alpha:a];
    return nil;
}

- (UIColor *)darkerColorForColor:(UIColor *)c
{
    CGFloat r, g, b, a;
    if ([c getRed:&r green:&g blue:&b alpha:&a])
        return [UIColor colorWithRed:MAX(r - 0.2, 0.0)
                               green:MAX(g - 0.2, 0.0)
                                blue:MAX(b - 0.2, 0.0)
                               alpha:a];
    return nil;
}

Utilisez-le comme ça :

UIColor *baseColor = // however you obtain your color
UIColor *lighterColor = [self lighterColorForColor:baseColor];
UIColor *darkerColor = [self darkerColorForColor:baseColor];

EDIT Comme @Anchu Chimala l'a souligné, pour une flexibilité maximale, ces méthodes devraient être implémentées comme une catégorie UIColor. De plus, d'après l'idée de @Riley, il peut être préférable de rendre la couleur plus foncée ou plus claire de manière proprtionnelle au lieu d'ajouter ou de soustraire des valeurs constantes. Comme @jrturton l'a souligné, il n'est pas nécessaire de manipuler les composants RVB ; il est préférable de modifier la propriété de luminosité elle-même. En résumé :

@implementation UIColor (LightAndDark)

- (UIColor *)lighterColor
{
    CGFloat h, s, b, a;
    if ([self getHue:&h saturation:&s brightness:&b alpha:&a])
        return [UIColor colorWithHue:h
                          saturation:s
                          brightness:MIN(b * 1.3, 1.0)
                               alpha:a];
    return nil;
}

- (UIColor *)darkerColor
{
    CGFloat h, s, b, a;
    if ([self getHue:&h saturation:&s brightness:&b alpha:&a])
        return [UIColor colorWithHue:h
                          saturation:s
                          brightness:b * 0.75
                               alpha:a];
    return nil;
}
@end

62voto

Aviel Gross Points 1110

TL;DR :

Swift :

extension UIColor {

    var lighterColor: UIColor {
        return lighterColor(removeSaturation: 0.5, resultAlpha: -1)
    }

    func lighterColor(removeSaturation val: CGFloat, resultAlpha alpha: CGFloat) -> UIColor {
        var h: CGFloat = 0, s: CGFloat = 0
        var b: CGFloat = 0, a: CGFloat = 0

        guard getHue(&h, saturation: &s, brightness: &b, alpha: &a)
            else {return self}

        return UIColor(hue: h,
                       saturation: max(s - val, 0.0),
                       brightness: b,
                       alpha: alpha == -1 ? a : alpha)
    }
}

Utilisation :

let lightColor = somethingDark.lighterColor

Objective-C :

- (UIColor *)lighterColorRemoveSaturation:(CGFloat)removeS
                              resultAlpha:(CGFloat)alpha {
    CGFloat h,s,b,a;
    if ([self getHue:&h saturation:&s brightness:&b alpha:&a]) {
        return [UIColor colorWithHue:h
                          saturation:MAX(s - removeS, 0.0)
                          brightness:b
                               alpha:alpha == -1? a:alpha];
    }
    return nil;
}

- (UIColor *)lighterColor {
    return [self lighterColorRemoveSaturation:0.5
                                  resultAlpha:-1];
}

@rchampourlier avait raison dans son commentaire à @user529758 (La réponse acceptée) - Les solutions HSB (ou HSV) et RGB donnent des résultats complètement différents. RGB ajoute simplement (ou rend la couleur plus proche) du blanc, et la solution HSB rapproche la couleur du bord de l'échelle de Brigtness - qui commence fondamentalement avec le noir et se termine avec la couleur pure...

En fait, la luminosité (valeur) rend la couleur plus ou moins proche du noir, tandis que la saturation la rend plus ou moins proche du blanc...

Comme vu ici :

HSV color graph

Ainsi, la solution pour rendre une couleur réellement plus claire (c'est-à-dire plus proche du blanc...) sera de rendre sa valeur de Saturation plus petit ce qui donne cette solution :

- (UIColor *)lighterColor {
    CGFloat h,s,b,a;
    if ([self getHue:&h saturation:&s brightness:&b alpha:&a]) {
        return [UIColor colorWithHue:h
                          saturation:MAX(s - 0.3, 0.0)
                          brightness:b /*MIN(b * 1.3, 1.0)*/
                               alpha:a];
    }
    return nil;
}

0 votes

Pour ce qui est de rendre les couleurs plus claires : J'ai obtenu le meilleur résultat en réduisant la saturation ET en augmentant la luminosité/la valeur. Cette réponse fonctionne très bien pour les couleurs "au-dessus" de la tarte dans l'image. Mais la plupart des couleurs vont se trouver quelque part "à l'intérieur" de la tarte. Pour les rapprocher du blanc, il faut également les déplacer "vers le haut" (en augmentant la valeur).

0 votes

L'augmentation de la valeur peut sembler fonctionner, mais ce ne sera pas la fonctionnalité "principale" de "obtenir une couleur plus claire". De la même manière, pour obtenir une couleur plus foncée, la bonne approche serait de diminuer uniquement la "valeur" et de laisser la saturation telle qu'elle est...

42voto

CryingHippo Points 3770

Swift extension universelle pour iOS et OS X en utilisant getHue :

#if os(OSX)

    import Cocoa
    public  typealias PXColor = NSColor

    #else

    import UIKit
    public  typealias PXColor = UIColor

#endif

    extension PXColor {

    func lighter(amount : CGFloat = 0.25) -> PXColor {
        return hueColorWithBrightnessAmount(1 + amount)
    }

    func darker(amount : CGFloat = 0.25) -> PXColor {
        return hueColorWithBrightnessAmount(1 - amount)
    }

    private func hueColorWithBrightnessAmount(amount: CGFloat) -> PXColor {
        var hue         : CGFloat = 0
        var saturation  : CGFloat = 0
        var brightness  : CGFloat = 0
        var alpha       : CGFloat = 0

        #if os(iOS)

            if getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) {
                return PXColor( hue: hue,
                                saturation: saturation,
                                brightness: brightness * amount,
                                alpha: alpha )
            } else {
                return self
            }

            #else

            getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)
            return PXColor( hue: hue,
                            saturation: saturation,
                            brightness: brightness * amount,
                            alpha: alpha )

        #endif

    }

}

Utilisation :

let color = UIColor(red: 0.5, green: 0.8, blue: 0.8, alpha: 1.0)
color.lighter(amount:0.5)
color.darker(amount:0.5)

OU (avec les valeurs par défaut) :

color.lighter()
color.darker()

Echantillon :

enter image description here

37voto

FredericP Points 556

Je voulais juste donner le même résultat, en RGB, que

  • placer la couleur avec alpha x% sur un fond blanc pour l'éclaircir
  • placer la couleur avec alpha x% sur un fond noir pour l'assombrir

Ce qui donne le même résultat, AFAIK, que de choisir la couleur dans un gradient 'couleur vers blanc' ou 'couleur vers noir', à x% de la taille du gradient.

À cette fin, le calcul est simple :

extension UIColor {
    func mix(with color: UIColor, amount: CGFloat) -> UIColor {
        var red1: CGFloat = 0
        var green1: CGFloat = 0
        var blue1: CGFloat = 0
        var alpha1: CGFloat = 0

        var red2: CGFloat = 0
        var green2: CGFloat = 0
        var blue2: CGFloat = 0
        var alpha2: CGFloat = 0

        getRed(&red1, green: &green1, blue: &blue1, alpha: &alpha1)
        color.getRed(&red2, green: &green2, blue: &blue2, alpha: &alpha2)

        return UIColor(
            red: red1 * (1.0 - amount) + red2 * amount,
            green: green1 * (1.0 - amount) + green2 * amount,
            blue: blue1 * (1.0 - amount) + blue2 * amount,
            alpha: alpha1
        )
    }
}

Voici des exemples avec quelques couleurs

Examples Darker and Lighter

24voto

Sebyddd Points 648

La solution de l'utilisateur529758 dans Swift :

Couleur plus foncée :

func darkerColorForColor(color: UIColor) -> UIColor {

       var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 0

       if color.getRed(&r, green: &g, blue: &b, alpha: &a){
           return UIColor(red: max(r - 0.2, 0.0), green: max(g - 0.2, 0.0), blue: max(b - 0.2, 0.0), alpha: a)
       }

       return UIColor()
}

Couleur plus claire :

func lighterColorForColor(color: UIColor) -> UIColor {

       var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 0

       if color.getRed(&r, green: &g, blue: &b, alpha: &a){
           return UIColor(red: min(r + 0.2, 1.0), green: min(g + 0.2, 1.0), blue: min(b + 0.2, 1.0), alpha: a)
       }

       return UIColor()
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X