Check if UIColor is dark or bright?

2020-01-27 10:04发布

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 readability.

Here's an example in Flash/Actionscript (with demo): http://web.archive.org/web/20100102024448/http://theflashblog.com/?p=173

Any thoughts?

Cheers, Andre

UPDATE

Thanks to everyone's suggestions, here's the working code:

- (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");
    }
}

Thanks once again :)

14条回答
我命由我不由天
2楼-- · 2020-01-27 10:26

If you want to find the brightness of the color, here is some 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);
}

If it is > 0.5 it is bright, and otherwise dark.

查看更多
淡お忘
3楼-- · 2020-01-27 10:29

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];
}
查看更多
家丑人穷心不美
4楼-- · 2020-01-27 10:29

For everything that's not grayish, the RGB inverse of a color is usually highly contrasted with it. The demo just inverts the color and desaturates it (converts it to a gray).

But generating a nice soothing combination of colors is quite complicated. Look at :

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

查看更多
祖国的老花朵
5楼-- · 2020-01-27 10:30

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
}
查看更多
小情绪 Triste *
6楼-- · 2020-01-27 10:30

My solution to this problem in a category (drawn from other answers here). Also works with grayscale colors, which at the time of writing none of the other answers do.

@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
查看更多
神经病院院长
7楼-- · 2020-01-27 10:30
- (BOOL)isColorLight:(UIColor*)color
{
    CGFloat white = 0;
    [color getWhite:&white alpha:nil];
    return (white >= .5);
}
查看更多
登录 后发表回答