我需要确定选定的UIColor(由用户选择)是暗还是亮,这样我就可以更改位于该颜色顶部的文本行的颜色,以提高可读性。
这是Flash / Actionscript中的一个示例(带演示): http://web.archive.org/web/20100102024448/http://theflashblog.com/?p=173
有什么想法吗?
干杯, 安德烈
更新
感谢大家的建议,这是工作代码:
- (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");
}
}
再次感谢:)
答案 0 :(得分:69)
W3C有以下内容: http://www.w3.org/WAI/ER/WD-AERT/#color-contrast
如果您只是黑色或白色文字,请使用上面的颜色亮度计算。如果低于125,请使用白色文本。如果是125或以上,请使用黑色文字。
编辑1:偏向黑色文字。 :)
编辑2:使用的公式是((红色值* 299)+(绿色值* 587)+(蓝色值* 114))/ 1000。
答案 1 :(得分:30)
使用Erik Nedwidek的答案,我提出了一小段代码,以便于包含。
- (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];
}
答案 2 :(得分:30)
此扩展适用于灰度颜色。但是,如果使用RGB初始化程序创建所有颜色而不使用UIColor.black
和UIColor.white
等内置颜色,则可能会删除其他检查。
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)
}
}
试验:
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")
}
注意:已更新至Swift 3 12/7/18
答案 3 :(得分:26)
Call<YoutubeResponse> call=service.searchVideos("snippet",s, URLConstants.Youtube_API_KEY);
答案 4 :(得分:7)
我在一个类别中解决这个问题(来自其他答案)。也适用于灰度颜色,在撰写本文时,没有其他答案可以使用。
@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
答案 5 :(得分:7)
Swift 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)
}
}
答案 6 :(得分:4)
Simpler 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
}
}
答案 7 :(得分:3)
如果您更喜欢块版本:
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;
};
答案 8 :(得分:2)
对于一些不是灰色的东西,颜色的RGB反转通常与它高度对比。 演示只是反转颜色并使其去饱和(将其转换为灰色)。
但是生成一种漂亮的舒缓颜色组合非常复杂。 看看:
http://particletree.com/notebook/calculating-color-contrast-for-legible-text/
答案 9 :(得分:2)
以下方法是基于白色的Swift语言发现颜色是浅色或深色。
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
}
以下方法使用颜色成分在Swift中找到颜色是浅色或深色。
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
}
答案 10 :(得分:2)
对于我只使用CGColorGetComponents没有工作,我得到2个组件为UIColors,如白色。所以我必须首先检查颜色spaceModel。 这就是我提出的最终成为@ mattsven答案的快速版本。
从此处获取的色彩空间: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
}
答案 11 :(得分:2)
UIColor具有以下转换为 HSB颜色空间的方法:
- (BOOL)getHue:(CGFloat *)hue saturation:(CGFloat *)saturation brightness:(CGFloat *)brightness alpha:(CGFloat *)alpha;
答案 12 :(得分:0)
如果你想找到颜色的亮度,这里有一些伪代码:
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);
}
如果是> 0.5它很亮,否则很暗。
答案 13 :(得分:0)
- (BOOL)isColorLight:(UIColor*)color
{
CGFloat white = 0;
[color getWhite:&white alpha:nil];
return (white >= .5);
}
答案 14 :(得分:0)
使用HandyUIKit可以使其成为不用脑筋的,例如:
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
只需在任何.hlca.luminance
个实例上使用 UIColor
即可为您提供正确的感知亮度值。大多数其他方法没有考虑到人类感知不同颜色(即使饱和度和亮度相同)在不同亮度级别的事实。 luminance
值会考虑到这一点。
阅读this great blog post或LAB color space上的维基百科条目以获取进一步说明。他们还将解释为什么 HSB颜色系统及其brightness
值仅为解决方案的一半。
正如提示:请注意纯绿色颜色的luminance
值远高于纯蓝色 > STRONG>。这仅仅是因为人类认为纯蓝色比纯绿色更暗。