Check if UIColor is dark or bright?

前端 未结 14 1965
醉酒成梦
醉酒成梦 2020-11-29 17:20

I need to determine whether a selected UIColor (picked by the user) is dark or bright, so I can change the color of a line of text that sits on top of that color, for better

相关标签:
14条回答
  • 2020-11-29 17:24

    Using Erik Nedwidek's answer, I came up with that little snippet of code for easy inclusion.

    - (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];
    }
    
    0 讨论(0)
  • 2020-11-29 17:27

    Following method is find color is light or dark in Swift language based on white in color.

    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
    }
    

    Following method is find color is light or dark in Swift using color components.

    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
    }
    
    0 讨论(0)
  • 2020-11-29 17:31

    Here is a Swift (3) extension to perform this check.

    This extension works with greyscale colors. However, if you are creating all your colors with the RGB initializer and not using the built in colors such as UIColor.black and UIColor.white, then possibly you can remove the additional checks.

    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: Updated to Swift 3 12/7/18

    0 讨论(0)
  • 2020-11-29 17:32

    Simpler Swift 3 extension:

    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
        }
    }
    
    0 讨论(0)
  • 2020-11-29 17:32

    UIColor has the following method to convert to HSB color space:

    - (BOOL)getHue:(CGFloat *)hue saturation:(CGFloat *)saturation brightness:(CGFloat *)brightness alpha:(CGFloat *)alpha;
    
    0 讨论(0)
  • 2020-11-29 17:34

    W3C has the following: http://www.w3.org/WAI/ER/WD-AERT/#color-contrast

    If you're only doing black or white text, use the color brightness calculation above. If it is below 125, use white text. If it is 125 or above, use black text.

    edit 1: bias towards black text. :)

    edit 2: The formula to use is ((Red value * 299) + (Green value * 587) + (Blue value * 114)) / 1000.

    0 讨论(0)
提交回复
热议问题