我希望能够将任何UIColor转换为渐变色。我的想法是使用Core Graphics来绘制一个渐变。我想做的是获取一种颜色,比如:
[UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0];
如何获取一个颜色比原来深或浅几个阴影。有谁知道怎么做吗?谢谢。
我希望能够将任何UIColor转换为渐变色。我的想法是使用Core Graphics来绘制一个渐变。我想做的是获取一种颜色,比如:
[UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0];
如何获取一个颜色比原来深或浅几个阴影。有谁知道怎么做吗?谢谢。
- (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的想法,将颜色按比例变暗或变亮可能是一个更好的主意,而不是添加或减去常量值。正如@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
getHue:saturation:brightness
这个方法,但它似乎使用HSV而不是HSB进行计算。在这种情况下改变亮度(实际上是值)将无效。例如,纯红色(rgb(255,0,0))的亮度/值为1,因此通过改变亮度调节亮度是不可能的。最终我选择对RGB值进行修改来解决问题。 - Romain ChampourliergetHue:saturation:brightness:alpha
会返回错误的结果。 - Matthieu Rieglerextension 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
- (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解决方案给出完全不同的结果。RGB只是添加(或使颜色更靠近)白色,而HSB解决方案将颜色更接近亮度比例尺上的边缘 - 基本上从黑色开始直到纯色...
基本上,亮度(值)使颜色更接近黑色或更远离黑色,而饱和度使其更接近白色或更远离白色...
如下图所示:
因此,使颜色实际上更明亮(即更接近白色...)的解决方案将是使其饱和度值更小,得到以下解决方案:
- (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;
}
Swift 是用于 iOS 和 OS X 的通用扩展,使用 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)
或者(使用默认值):
color.lighter()
color.darker()
示例:
let color = usingColorSpaceName(NSCalibratedRGBColorSpace)
然后将 getHue
调用替换为对 color
的调用:
color?.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)
- Oskarprivate func hueColorWithBrightnessAmount(_ amount: CGFloat) -> PXColor {
。 - Codemonk0
而是等于1
吗?因为变量var brightness : CGFloat = 1
的值是1
。 - denis_lor我只想提供与以下相同的RGB结果:
根据我所知,这样做会得到与在“颜色到白色”或“颜色到黑色”的渐变中以 x% 渐变大小选择颜色得到的结果相同。
为了达到这个目的,数学很简单:
extension UIColor {
func mix(with color: UIColor, amount: CGFloat) -> UIColor {
var red1: CGFloat = 0
var green1: CGFloat = 0
var blue1: CGFloat = 0
var alpha1: CGFloat = 0
var red2: CGFloat = 0
var green2: CGFloat = 0
var blue2: CGFloat = 0
var alpha2: CGFloat = 0
getRed(&red1, green: &green1, blue: &blue1, alpha: &alpha1)
color.getRed(&red2, green: &green2, blue: &blue2, alpha: &alpha2)
return UIColor(
red: red1 * (1.0 - amount) + red2 * amount,
green: green1 * (1.0 - amount) + green2 * amount,
blue: blue1 * (1.0 - amount) + blue2 * amount,
alpha: alpha1
)
}
}
这里是带有一些颜色的示例
user529758的Swift解决方案:
较暗的颜色:
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()
}
var darker: UIColor
,那么它会更方便。 - Bruno Philipe如果将RGB颜色转换为HSL颜色模型,则可以通过变化L = 亮度分量从L = 0.0(黑色)到L = 0.5(自然颜色)再到L = 1.0(白色)。UIColor
无法直接处理HSL,但有用于转换RGB <-> HSL的公式。
这个线程中的所有其他答案都使用 RGB 颜色系统 或者仅仅是改变 HSB 系统的色相或亮度值。正如 这篇优秀的博客文章 中详细解释的那样,使颜色变浅或变暗的正确方法是改变其 亮度
值。其他答案都没有这样做。如果你想做得正确,那么就 使用我的解决方案 或者在阅读了博客文章后自己编写。
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)
还有一种选项是应用相对变化(推荐):
// create a new UIColor object with slightly darker color
color.change(.luminance, by: -0.2)
Sebyddd
方案作为一个扩展:
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扩展。
具体来说,它在HSL实现中有一个lighten函数:(UIColor *)lighten:(CGFloat)amount
- 它完美地解决了问题。
Swift 5
extension UIColor {
func lighter(by percentage:CGFloat=30.0) -> UIColor? {
return self.adjust(by: abs(percentage) )
}
func darker(by percentage:CGFloat=30.0) -> UIColor? {
return self.adjust(by: -1 * abs(percentage) )
}
func adjust(by percentage:CGFloat=30.0) -> 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 + percentage/100, 1.0),
green: min(g + percentage/100, 1.0),
blue: min(b + percentage/100, 1.0),
alpha: a)
} else {
return nil
}
}
}