从UIColor获得略微更亮和更暗的颜色

Cor*_*ode 143 gradient core-graphics objective-c uicolor ios

我希望能够将任何UIColor变成渐变.我打算这样做的方法是使用Core Graphics绘制渐变.我想要做的是获得一种颜色,让我们说:

[UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0];
Run Code Online (Sandbox Code Playgroud)

并得到一个UIColor,这是一些深色调和一些浅色调.有谁知道如何做到这一点?谢谢.

小智 276

- (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;
}
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

UIColor *baseColor = // however you obtain your color
UIColor *lighterColor = [self lighterColorForColor:baseColor];
UIColor *darkerColor = [self darkerColorForColor:baseColor];
Run Code Online (Sandbox Code Playgroud)

编辑:正如@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
Run Code Online (Sandbox Code Playgroud)

  • 如果它们用于灰色阴影,则此方法将失败.`getHue:saturation:brightness:alpha`将返回FALSE. (4认同)
  • 为什么在使用色调,饱和度,亮度时才能使用RGB,然后只需重新调整亮度就可以重建颜色? (2认同)
  • 我自己一直在尝试使用HSB版本,但它没有按预期工作.尽管UIKit的'getHue:saturation:brightness`签名,它似乎适用于HSV而不是HSB.在此上下文中更改亮度(实际上是值)将不起作用.例如,纯红色(rgb(255,0,0))的亮度/值为1​​,因此不可能使亮度变亮.我最终改变了RGB值的变化. (2认同)
  • 我认为你的答案中有一些令人困惑的地方:你采用两种方法(一种用RGB,另一种用HSB用于类别版本),这些方法没有相同的结果......这可能是一个问题意思是:闪电确实对我来说使颜色趋于白色(变暗到黑色),而改变亮度/值使它更强(更轻). (2认同)
  • 我想知道为什么这是*接受的答案*,因为**两个**建议的解决方案都是**不正确的**。它们都只是改变了*理论值*,与人类感知的“更亮”或“更暗”颜色几乎没有关系。我建议阅读**这篇很棒的文章**(短链接:goo.gl/qqgk9V)来理解我的意思。它解释了 LAB 色彩空间的**`luminance` 值** 是您在使颜色变亮/变暗时真正应该关心的值。请参阅 [我的回答](http://stackoverflow.com/a/38130780/3451975) **如何使用它** 并以正确的方式解决此问题。 (2认同)

Avi*_*oss 55

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

let lightColor = somethingDark.lighterColor
Run Code Online (Sandbox Code Playgroud)

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];
}
Run Code Online (Sandbox Code Playgroud)

@rchampourlier对@ user529758的评论是正确的(接受的答案) - HSB(或HSV)和RGB解决方案给出了完全不同的结果.RGB只是增加(或使颜色更接近)白色,HSB解决方案使颜色更接近Brigtness量表的边缘 - 基本上以黑色开始,以纯色结束......

基本上亮度(值)使颜色更接近或更接近黑色,其中饱和度使其更接近白色...

如下所示:

HSV颜色图

因此,使颜色更明亮(即更接近白色......)的解决方案是使其饱和度值更小,从而得出此解决方案:

- (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;
}
Run Code Online (Sandbox Code Playgroud)


Cry*_*ppo 38

使用getHue的iOS和OS X的Swift通用扩展:

#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

    }

}
Run Code Online (Sandbox Code Playgroud)

用法:

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)
Run Code Online (Sandbox Code Playgroud)

或(使用默认值):

color.lighter()
color.darker()
Run Code Online (Sandbox Code Playgroud)

样品:

在此输入图像描述

  • 通过添加以下内容来修复该问题:添加“ let color = usingColorSpaceName(NSCalibratedRGBColorSpace)”,然后将getHue调用替换为对颜色的调用:color?.getHue(&hue,饱和度:&saturation,亮度:&brightness,alpha:&alpha)。 (2认同)

Fre*_*icP 24

我只是想用RGB来给出相同的结果

  • 将alpha x%的颜色放在白色背景上以减轻亮度
  • 将alpha x%的颜色放在黑色背景上以使其变暗

其结果与AFAIK相同,而是以渐变"颜色变为白色"或"颜色变为黑色",以渐变大小的x%选择颜色.

为此,数学很简单:

// UIColor+Mix.swift
import UIKit
extension UIColor {

    func mixLighter (amount: CGFloat = 0.25) -> UIColor {
        return mixWithColor(UIColor.white, amount:amount)
    }

    func mixDarker (amount: CGFloat = 0.25) -> UIColor {
        return mixWithColor(UIColor.black, 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 )
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是一些颜色的示例

示例更暗更亮


Seb*_*ddd 23

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()
}
Run Code Online (Sandbox Code Playgroud)

颜色较浅:

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()
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*n R 13

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

  • HSL和HSB(有时也称为HSV)颜色模型之间的差异在于HSB中L = 1.0对应于纯色,而在HSL中L = 1.0对应于白色而L = 0.5对应于纯色.由于原始海报要求例如使蓝色(RGB = 0/0/1)变浅的方法,我认为HSL更灵活. (8认同)

Rya*_*anM 6

该解决方案中没有贴出相当工作了所有的颜色和色调,但后来我偶然发现这个库它提供了一套很好的实现扩展的UIColor的.

具体来说,它具有减轻功能,作为其HSL实施的一部分:(UIColor *)lighten:(CGFloat)amount- 完美运行.


Jee*_*hut 5

此线程中的所有其他答案都使用RGB 颜色系统,或者只是更改HSB 系统色调或亮度值。正如这篇很棒的博客文章中详细解释的那样,使颜色变亮或变暗的正确方法是更改​​其luminance值。其他答案都没有这样做。如果你想把它做对,那么使用我的解决方案或在阅读博客文章后编写自己的解决方案


不幸的是,默认情况下更改 UIColor任何属性都非常麻烦。此外,Apple 甚至不支持任何基于 LAB 的色彩空间,如类中的 HCL (在 LAB 中是我们正在寻找的值)。UIColorLluminance

使用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)
Run Code Online (Sandbox Code Playgroud)

还有一个选项可以应用相对更改(推荐):

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

请注意,HandyUIKit 还在您的项目中添加了一些其他方便的 UI 功能——查看 GitHub 上的自述文件以了解更多详细信息。

我希望它有帮助!

免责声明:我是 HandyUIKit 的作者。


Hem*_*ang 5

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()
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

let darkerYellow = UIColor.yellow.darker()
let lighterYellow = UIColor.yellow.lighter()
Run Code Online (Sandbox Code Playgroud)


Alf*_*lfi 5

雨燕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
     }
   }
}
Run Code Online (Sandbox Code Playgroud)