Vérifiez si la couleur UIColor est sombre ou shinye?

Je dois déterminer si une couleur UIColor sélectionnée (sélectionnée par l’utilisateur) est sombre ou shinye. Je peux donc changer la couleur d’une ligne de texte qui se trouve au-dessus de cette couleur pour une meilleure lisibilité.

Voici un exemple en Flash / Actionscript (avec démo): http://theflashblog.com/?p=173

Des pensées?

Cheers, Andre

METTRE À JOUR

Grâce aux suggestions de tous, voici le code de travail:

- (void) updateColor:(UIColor *) newColor { const CGFloat *componentColors = CGColorGetComponents(newColor.CGColor); CGFloat colorBrightness = ((componentColors[0] * 299) + (componentColors[1] * 587) + (componentColors[2] * 114)) / 1000; if (colorBrightness < 0.5) { NSLog(@"my color is dark"); } else { NSLog(@"my color is light"); } } 

Encore merci 🙂

Le W3C dispose des éléments suivants: http://www.w3.org/WAI/ER/WD-AERT/#color-contrast

Si vous ne faites que du texte noir ou blanc, utilisez le calcul de luminosité de couleur ci-dessus. S’il est inférieur à 125, utilisez du texte blanc. S’il est égal ou supérieur à 125, utilisez du texte noir.

edit 1: biais vers le texte noir. 🙂

edit 2: La formule à utiliser est ((valeur rouge * 299) + (valeur verte * 587) + (valeur bleue * 114)) / 1000.

En utilisant la réponse d’Erik Nedwidek, j’ai trouvé ce petit extrait de code pour une inclusion facile.

 - (UIColor *)readableForegroundColorForBackgroundColor:(UIColor*)backgroundColor { size_t count = CGColorGetNumberOfComponents(backgroundColor.CGColor); const CGFloat *componentColors = CGColorGetComponents(backgroundColor.CGColor); CGFloat darknessScore = 0; if (count == 2) { darknessScore = (((componentColors[0]*255) * 299) + ((componentColors[0]*255) * 587) + ((componentColors[0]*255) * 114)) / 1000; } else if (count == 4) { darknessScore = (((componentColors[0]*255) * 299) + ((componentColors[1]*255) * 587) + ((componentColors[2]*255) * 114)) / 1000; } if (darknessScore >= 125) { return [UIColor blackColor]; } return [UIColor whiteColor]; } 

Swift3

 extension UIColor { var isLight: Bool { var white: CGFloat = 0 getWhite(&white, alpha: nil) return white > 0.5 } } // Usage if color.isLight { label.textColor = UIColor.black } else { label.textColor = UIColor.white } 

Voici une extension Swift (3) pour effectuer ce contrôle.

Cette extension fonctionne avec des couleurs en niveaux de gris. Toutefois, si vous créez toutes vos couleurs avec l’initialiseur RVB et que vous n’utilisez pas les couleurs UIColor.black telles que UIColor.black et UIColor.white , vous pouvez éventuellement supprimer les vérifications supplémentaires.

 extension UIColor { // Check if the color is light or dark, as defined by the injected lightness threshold. // Some people report that 0.7 is best. I suggest to find out for yourself. // A nil value is returned if the lightness couldn't be determined. func isLight(threshold: Float = 0.5) -> Bool? { let originalCGColor = self.cgColor // Now we need to convert it to the RGB colorspace. UIColor.white / UIColor.black are greyscale and not RGB. // If you don't do this then you will crash when accessing components index 2 below when evaluating greyscale colors. let RGBCGColor = originalCGColor.converted(to: CGColorSpaceCreateDeviceRGB(), intent: .defaultIntent, options: nil) guard let components = RGBCGColor?.components else { return nil } guard components.count >= 3 else { return nil } let brightness = Float(((components[0] * 299) + (components[1] * 587) + (components[2] * 114)) / 1000) return (brightness > threshold) } } 

Tests:

 func testItWorks() { XCTAssertTrue(UIColor.yellow.isLight()!, "Yellow is LIGHT") XCTAssertFalse(UIColor.black.isLight()!, "Black is DARK") XCTAssertTrue(UIColor.white.isLight()!, "White is LIGHT") XCTAssertFalse(UIColor.red.isLight()!, "Red is DARK") } 

Note: Mis à jour pour Swift 3 12/7/18

Version rapide 4

 extension UIColor { func isLight() -> Bool { guard let components = cgColor.components, components.count > 2 else {return false} let brightness = ((components[0] * 299) + (components[1] * 587) + (components[2] * 114)) / 1000 return (brightness > 0.5) } } 

Ma solution à ce problème dans une catégorie (tirée d’autres réponses ici). Fonctionne également avec des couleurs en niveaux de gris, ce qui, au moment de la rédaction, ne correspond à aucune des autres réponses.

 @interface UIColor (Ext) - (BOOL) colorIsLight; @end @implementation UIColor (Ext) - (BOOL) colorIsLight { CGFloat colorBrightness = 0; CGColorSpaceRef colorSpace = CGColorGetColorSpace(self.CGColor); CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace); if(colorSpaceModel == kCGColorSpaceModelRGB){ const CGFloat *componentColors = CGColorGetComponents(self.CGColor); colorBrightness = ((componentColors[0] * 299) + (componentColors[1] * 587) + (componentColors[2] * 114)) / 1000; } else { [self getWhite:&colorBrightness alpha:0]; } return (colorBrightness >= .5f); } @end 

Plus simple extension Swift 3:

 extension UIColor { func isLight() -> Bool { guard let components = cgColor.components else { return false } let redBrightness = components[0] * 299 let greenBrightness = components[1] * 587 let blueBrightness = components[2] * 114 let brightness = (redBrightness + greenBrightness + blueBrightness) / 1000 return brightness > 0.5 } } 

Si vous préférez la version en bloc:

 BOOL (^isDark)(UIColor *) = ^(UIColor *color){ const CGFloat *component = CGColorGetComponents(color.CGColor); CGFloat brightness = ((component[0] * 299) + (component[1] * 587) + (component[2] * 114)) / 1000; if (brightness < 0.75) return YES; return NO; }; 

Pour tout ce qui n’est pas grisâtre, l’inverse RVB d’une couleur est généralement très contrasté. La démo inverse simplement la couleur et la désature (la convertit en gris).

Mais générer une belle combinaison de couleurs apaisante est assez compliqué. Regarder :

http://particletree.com/notebook/calculating-color-contrast-for-legible-text/

La méthode suivante consiste à trouver la couleur claire ou foncée dans le langage Swift en fonction de la couleur blanche.

 func isLightColor(color: UIColor) -> Bool { var white: CGFloat = 0.0 color.getWhite(&white, alpha: nil) var isLight = false if white >= 0.5 { isLight = true NSLog("color is light: %f", white) } else { NSLog("Color is dark: %f", white) } return isLight } 

La méthode suivante est de trouver la couleur claire ou sombre dans Swift en utilisant des composants de couleur.

 func isLightColor(color: UIColor) -> Bool { var isLight = false var componentColors = CGColorGetComponents(color.CGColor) var colorBrightness: CGFloat = ((componentColors[0] * 299) + (componentColors[1] * 587) + (componentColors[2] * 114)) / 1000; if (colorBrightness >= 0.5) { isLight = true NSLog("my color is light") } else { NSLog("my color is dark") } return isLight } 

Pour moi, utiliser uniquement CGColorGetComponents n’a pas fonctionné, je reçois 2 composants pour les UIColors comme le blanc. Donc, je dois d’abord vérifier l’espace colorimésortingque. C’est ce que j’ai découvert et qui a été la version rapide de la réponse de @matstsv.

Espace colorimésortingque pris ici: https://stackoverflow.com/a/16981916/4905076

 extension UIColor { func isLight() -> Bool { if let colorSpace = self.cgColor.colorSpace { if colorSpace.model == .rgb { guard let components = cgColor.components, components.count > 2 else {return false} let brightness = ((components[0] * 299) + (components[1] * 587) + (components[2] * 114)) / 1000 return (brightness > 0.5) } else { var white : CGFloat = 0.0 self.getWhite(&white, alpha: nil) return white >= 0.5 } } return false } 

Si vous voulez trouver la luminosité de la couleur, voici un pseudo-code:

 public float GetBrightness(int red, int blue, int green) { float num = red / 255f; float num2 = blue / 255f; float num3 = green / 255f; float num4 = num; float num5 = num; if (num2 > num4) num4 = num2; if (num3 > num4) num4 = num3; if (num2 < num5) num5 = num2; if (num3 < num5) num5 = num3; return ((num4 + num5) / 2f); } 

Si c'est> 0.5, il est clair et sombre.

 - (BOOL)isColorLight:(UIColor*)color { CGFloat white = 0; [color getWhite:&white alpha:nil]; return (white >= .5); } 

Utiliser HandyUIKit en fait une évidence , par exemple:

 import HandyUIKit UIColor.black.hlca.luminance // => 0.0 UIColor.white.hlca.luminance // => 1.0 UIColor.lightGray.hlca.luminance // => 0.70 UIColor.darkGray.hlca.luminance // => 0.36 UIColor.red.hlca.luminance // => 0.53 UIColor.green.hlca.luminance // => 0.87 UIColor.blue.hlca.luminance // => 0.32 

Utiliser simplement .hlca.luminance sur une instance UIColor vous donnera la valeur correcte pour la légèreté perçue . La plupart des autres approches ne prennent pas en compte le fait que les humains perçoivent des couleurs différentes (même si la saturation et la luminosité sont les mêmes) à différents niveaux de luminosité . Les valeurs de luminance en tiennent compte.

Lisez cet excellent article de blog ou l’entrée Wikipedia sur l’ espace colorimésortingque de LAB pour plus d’explications. Ils expliquent également pourquoi le système de couleurs HSB avec sa valeur de brightness ne représente que la moitié de la solution.

Juste comme un conseil: Notez que la valeur de luminance de la couleur verte pure est beaucoup plus élevée que sur la couleur bleue pure . C’est simplement parce que les humains perçoivent le bleu pur comme une couleur beaucoup plus sombre que le vert pur.