首页 文章

从UIColor获得略微更浅和更深的颜色

提问于
浏览
138

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

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

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

17 回答

  • 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];
    

    EDIT :正如@Anchu Chimala所指出的,为了获得最大的灵活性,这些方法应该作为UIColor类实现 . 另外,@ Riley 's idea, it may be a better idea to make the color proprtionally darker or lighter instead of adding or subtracting constant values. As @jrturton pointed out, it'不需要操纵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
    
  • 13

    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解决方案给出了完全不同的结果 . RGB只是增加(或使颜色更接近)白色,而HSB解决方案使颜色更接近Brigtness量表的边缘 - 基本上以黑色开始,以纯色结束......

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

    如下所示:

    HSV color graph

    因此,使颜色实际上更亮(即更接近白色......)的解决方案是使其饱和度值 smaller ,从而得到此解决方案:

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

    Swift iOS and 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()
    

    样品:

    enter image description here

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

    更浅的颜色:

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

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

    • 将alpha x%的颜色放在白色背景上以减轻亮度

    • 将带有alpha x%的颜色放在黑色背景上以使其变暗

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

    为此,数学很简单:

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

    Here are examples with some colors

    Examples Darker and Lighter

  • 2

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

  • 51

    所有解决方案都没有适用于所有颜色和阴影,但随后我偶然发现了this library,它为UIColor提供了一套非常好的实现扩展 .

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

  • 1

    如果您希望user529758的解决方案使用灰色阴影(例如 [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 .

  • 0

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

    Sebyddd solution as an extension:

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

    Usage:

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

    我不确定你是否正在寻找某种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];
    

    选择另一个比例因子,比如0.8:

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

    这是你正在寻找的那种效果吗?

  • 0

    此主题中的所有其他答案都使用 either the RGB color system 或只是更改 hue or brightness value of the HSB system . 正如this great blog post中详细解释的那样,使颜色变浅或变暗的正确方法是更改其 luminance 值 . 没有其他答案那样做 . 如果你想做得对,那么在阅读博客文章后 use my solutionwrite your own .


    不幸的是,改变UIColor by default 的任何属性都是 quite a hassle . 此外,Apple甚至不支持 UIColor 类中任何基于LAB的色彩空间,如HCL(LAB中的 L 是我们正在寻找的 luminance 值) .

    使用 HandyUIKit (通过Carthage安装)增加了对 HCL 的支持并使你的生活 a lot easier

    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)
    

    还可以选择应用 relative change (推荐):

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

    请注意,HandyUIKit还会在项目中添加 some other handy UI features - 有关详细信息,请查看README on GitHub .

    我希望它有所帮助!

  • 272

    理想情况下,函数应封装在名为 UIColor+Brightness.swiftUIColor 扩展中,并具有可配置的亮度 - 请参见下面的示例:

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

    我根据状态值渲染彩色单元格:

    status-images

    为此我在使用CryingHippo的建议收到错误后,根据一些旧的objc代码写了一个swift扩展:

    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 的作用相同同样 . 只需将 UIColor 替换为 NSColor 即可 .

  • 0

    这是一个UIColor类别,它还允许控制颜色变化量 .

    - (UIColor *)lighterColorWithDelta:(CGFloat)delta
    {
        CGFloat r, g, b, a;
        if ([self getRed:&r green:&g blue:&b alpha:&a])
            return [UIColor colorWithRed:MIN(r + delta, 1.0)
                                   green:MIN(g + delta, 1.0)
                                    blue:MIN(b + delta, 1.0)
                                   alpha:a];
        return nil;
    }
    
    - (UIColor *)darkerColorWithDelta:(CGFloat)delta
    {
        CGFloat r, g, b, a;
        if ([self getRed:&r green:&g blue:&b alpha:&a])
            return [UIColor colorWithRed:MAX(r - delta, 0.0)
                                   green:MAX(g - delta, 0.0)
                                    blue:MAX(b - delta, 0.0)
                                   alpha:a];
        return nil;
    }
    
  • 2

    A Swift extension based on @Sebyddd answer:

    import Foundation
    import UIKit
    
    extension UIColor{
        func colorWith(brightness: CGFloat) -> UIColor{
            var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 0
    
            if getRed(&r, green: &g, blue: &b, alpha: &a){
                return UIColor(red: max(r + brightness, 0.0), green: max(g + brightness, 0.0), blue: max(b + brightness, 0.0), alpha: a)
            }
    
            return UIColor()
        }
    }
    
  • 0

    Tested in Xcode 10 with Swift 4.x for iOS 12

    从你的颜色开始作为UIColor并选择变暗因子(作为CGFloat)

    let baseColor = UIColor.red
    let darkenFactor: CGFloat = 2
    

    CGColor类型具有可选值 components ,它将颜色分解为RGBA(作为CGFloat数组,其值介于0和1之间) . 然后,您可以使用从CGColor中获取的RGBA值重建UIColor并对其进行操作 .

    let darkenedBase = UIColor(displayP3Red: startColor.cgColor.components![0] / darkenFactor, green: startColor.cgColor.components![1] / darkenFactor, blue: startColor.cgColor.components![2] / darkenFactor, alpha: 1)
    

    在这个例子中,每个RGB值被除以2,使得颜色一半变暗 . alpha值保持不变,但您可以选择将暗因子应用于alpha值而不是RGB .

相关问题