从UIColor获得稍微更亮和更深的颜色

我正在寻找能够把任何UIColor变成一个渐变。 我打算这样做的方式是使用Core Graphics绘制渐变。 我想要做的是获得一个颜色,让我们说:

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

并得到一个颜色深一些,色调较浅的UIColor。 有谁知道如何做到这一点? 谢谢。

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

像这样使用它:

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

编辑 :@Anchu Chimala指出,为了获得最大的灵活性,这些方法应该作为一个UIColor类来实现。 另外,从@ Riley的想法来看,可能更好的做法是让颜色变得更暗或更轻,而不是增加或减less常量值。 正如@jrturton指出的那样,没有必要操纵RGB组件。 修改亮度属性本身更好。 总而言之:

 @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 

TL; DR:

迅速:

 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) } } 

用法:

 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在对@ user529758(接受的答案)的评论中是正确的 – HSB(或HSV)和RGB解决scheme给出了完全不同的结果。 RGB只是增加(或使颜色更接近)白色,HSB解决scheme使颜色更接近Brigtness比例的边缘 – 基本上以黑色开始,以纯色结束…

基本上亮度(价值)使颜色越来越接近黑色,饱和度使其越来越接近白色。

如这里所见:

HSV颜色图表

因此,使颜色更明亮(即接近白色)的解决scheme将使饱和度值更小 ,从而产生以下解决scheme:

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

适用于iOS和OS X的 Swift通用扩展,使用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 } } 

用法:

 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) 

OR(使用默认值):

 color.lighter() color.darker() 

示例:

在这里输入图像说明

user529758在Swift中的解决scheme:

较深的颜色:

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

更轻的颜色:

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

如果将RGB颜色转换为HSL颜色模型,则可以将L = 0.5(自然色)中L = 0.0(黑色)的L =亮度分量更改为L = 1.0(白色)。 UIColor不能直接处理HSL,但有转换RGB < – > HSL的公式。

我只是想在RGB中给出相同的结果

  • 将阿尔法x%的颜色放置在白色背景上以减轻亮度
  • 将黑色背景上的阿尔法x%的颜色放置变暗

在渐变大小的x%处,以相同的结果(AFAIK)获得相同的结果,而不是以渐变的“颜色到白色”或“颜色到黑色”来select颜色。

为此,math很简单:

 // UIColor+Mix.swift import UIKit extension UIColor { func mixLighter (amount: CGFloat = 0.25) -> UIColor { return mixWithColor(UIColor.whiteColor(), amount:amount) } func mixDarker (amount: CGFloat = 0.25) -> UIColor { return mixWithColor(UIColor.blackColor(), amount:amount) } func mixWithColor(color: UIColor, amount: CGFloat = 0.25) -> UIColor { var r1 : CGFloat = 0 var g1 : CGFloat = 0 var b1 : CGFloat = 0 var alpha1 : CGFloat = 0 var r2 : CGFloat = 0 var g2 : CGFloat = 0 var b2 : CGFloat = 0 var alpha2 : CGFloat = 0 self.getRed (&r1, green: &g1, blue: &b1, alpha: &alpha1) color.getRed(&r2, green: &g2, blue: &b2, alpha: &alpha2) return UIColor( red:r1*(1.0-amount)+r2*amount, green:g1*(1.0-amount)+g2*amount, blue:b1*(1.0-amount)+b2*amount, alpha: alpha1 ) } } 

这里有一些颜色的例子

例子更深和更轻

没有一个解决scheme对所有的颜色和阴影都非常有用,但是后来我偶然发现了这个库 ,它为UIColor提供了一套非常好的扩展。

具体来说,它具有一个亮点function作为其HSL实现的一部分: (UIColor *)lighten:(CGFloat)amount – 这是完美的作品。

如果你想让user529758的解决scheme使用灰色阴影(比如[UIColor lightGrayColor][UIColor darkGrayColor]你必须像这样改进它:

 - (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]; } CGFloat white, alpha; if ([self getWhite:&white alpha:&alpha]) { white = MIN(1.3*white, 1.0); return [UIColor colorWithWhite:white alpha:alpha]; } return nil; } 

getHue:saturation:brightness:alpha在灰色阴影中调用时失败(并返回false ),因此您需要使用getWhite:alpha

UIColor扩展和固定lighterColorForColor

 extension UIColor { class 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() } class 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){ let tmpColor = UIColor(red: min(r + 0.2, 1.0), green: min(g + 0.2, 1.0), blue: min(b + 0.2, 1.0), alpha: a) println(tmpColor) return tmpColor } return UIColor() } } 

我不确定你是否正在寻找某种Objective-C的答案,但是根据RGBA指定的颜色的工作原理,我认为你可以简单地根据任意因子来缩放RGB值,以获得“更轻”或“较暗”的阴影。 例如,你可能有一个蓝色的:

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

想要一个更深的蓝色? 将RGB值乘以0.9:

 [UIColor colorWithRed:0.0 green:0.0 blue:0.9 alpha:1.0]; 

瞧。 或者,也许你有一个橙色:

 [UIColor colorWithRed:1.0 green:0.4 blue:0.0 alpha:1.0]; 

select另一个比例因子,比如0.8:

 [UIColor colorWithRed:0.8 green:0.32 blue:0.0 alpha:1.0]; 

这是你要找的那种效果吗?

作为扩展的Sebyddd解决scheme:

 extension UIColor { func darker() -> UIColor { var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 0 if self.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() } func lighter() -> UIColor { var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 0 if self.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() } } 

用法:

 let darkerYellow = UIColor.yellow.darker() let lighterYellow = UIColor.yellow.lighter() 

理想情况下,这些函数应该封装在名为UIColor+Brightness.swiftUIColor扩展中,并具有可configuration的亮度 – 请参阅下面的示例:

 import UIKit extension UIColor { func lighterColorWithBrightnessFactor(brightnessFactor:CGFloat) -> UIColor { var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 0 if self.getRed(&r, green:&g, blue:&b, alpha:&a) { return UIColor(red:min(r + brightnessFactor, 1.0), green:min(g + brightnessFactor, 1.0), blue:min(b + brightnessFactor, 1.0), alpha:a) } return UIColor() } } 

我根据状态值呈现彩色单元格:

状态图像

为此,我在使用CryingHippo的build议发现错误之后,基于一些旧的objc代码写了一个快速扩展:

 extension UIColor{ func darker(darker: CGFloat) -> UIColor{ var red: CGFloat = 0.0 var green: CGFloat = 0.0 var blue: CGFloat = 0.0 if self.colorSpace == UIColorSpace.genericGrayColorSpace(){ red = whiteComponent - darker green = whiteComponent - darker blue = whiteComponent - darker } else { red = redComponent - darker green = greenComponent - darker blue = blueComponent - darker } if red < 0{ green += red/2 blue += red/2 } if green < 0{ red += green/2 blue += green/2 } if blue < 0{ green += blue/2 red += blue/2 } return UIColor( calibratedRed: red, green: green, blue: blue, alpha: alphaComponent ) } func lighter(lighter: CGFloat) -> UIColor{ return darker(-lighter) } } 

NSColor也是如此。 只需用NSColorreplaceUIColor NSColor

此线程中的所有其他答案都使用RGB颜色系统,或者仅更改HSB系统色调或亮度值 。 正如在这个伟大的博客文章中详细解释的,使颜色变浅或变暗的正确方法是改变其luminance值。 没有其他的答案是这样的。 如果你想做正确的事,那么使用我的解决scheme或者在阅读博客文章后写下自己的 解决scheme


不幸的是,默认情况下 ,更改UIColor 任何属性是相当麻烦的 。 此外,苹果甚至不支持在UIColor类中的任何基于LAB的色彩空间(如HCL)(LAB中的L是我们正在查找的luminance值)。

使用HandyUIKit (通过Carthage安装)增加了对HCL的支持,让你的生活变得更加简单

 import HandyUIKit let color = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 1.0) // create a new UIColor object with a specific luminance (slightly lighter) color.change(.luminance, to: 0.7) 

还可以select应用相对更改 (推荐):

 // create a new UIColor object with slightly darker color color.change(.luminance, by: -0.2) 

请注意,HandyUIKit还在您的项目中添加了一些其他方便的UIfunction – 在GitHub上检出其自述文件以获取更多详细信息。

我希望它有帮助!