ios 从 UIColor 获得更浅和更深的颜色

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11598043/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 19:22:31  来源:igfitidea点击:

Get Slightly Lighter and Darker Color from UIColor

objective-cioscore-graphicsgradientuicolor

提问by CoreCode

I was looking to be able to turn any UIColor into a gradient. The way I am intending to do this is by using Core Graphics to draw a gradient. What I am trying to do is to get a color, lets say:

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

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

and get a UIColor which is a few shades darker and a few shades lighter. Does anyone know how to do this? Thank you.

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

回答by

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

Use it like this:

像这样使用它:

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

EDIT: as @Anchu Chimala pointed out, for maximum flexibility, these methods should be implemented as an UIColor category. Also, from @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's not necessary to manipulate the RGB components; it's better to modify the brightness property itself. All in all:

编辑:正如@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

回答by Aviel Gross

TL;DR:

特尔;博士:

Swift:

迅速:

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

Usage:

用法:

let lightColor = somethingDark.lighterColor

Objective-C:

目标-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 was right in his comment to @user529758 (The accepted answer) - The HSB (Or HSV) and RGB solutions give completely different results. RGB just adds (Or makes the color closer to) white, and the HSB solution brings the color closer to the edge in the Brigtness scale - which basically start with black and ends with the pure color...

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

Basically Brightness (Value) makes the color less or more closer to black, where Saturation makes it less or more closer to white...

基本上,亮度(值)使颜色更接近于黑色,而饱和度使其更接近于白色……

As seen here:

如这里所见:

HSV color graph

HSV 彩色图

So the solution to make a color actually brighter (i.e. closer to white...) will be to make it's Saturation value smaller, resulting this solution:

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

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

回答by CryingHippo

Swiftuniversal extension for iOS and OS X, using getHue:

适用于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

    }

}

Usage :

用法 :

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 (with the default values):

或(使用默认值):

color.lighter()
color.darker()

Sample :

样本 :

enter image description here

在此处输入图片说明

回答by FredericP

I just wanted to give the same result, in RGB, than

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

  • placing the color with alpha x% over a white background to lighten
  • placing the color with alpha x% over a black background to darken
  • 将带有 alpha x% 的颜色放置在白色背景上以变亮
  • 将带有 alpha x% 的颜色放置在黑色背景上以变暗

Which gives the same result, AFAIK, than picking the color in a gradient 'color to white' or 'color to black', at x% of the gradient size.

这给出了相同的结果,AFAIK,而不是在渐变大小的 x% 处选择“颜色到白色”或“颜色到黑色”渐变中的颜色。

For that purpose, the math is simple:

为此,数学很简单:

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

Here are examples with some colors

以下是一些颜色的示例

Examples Darker and Lighter

更深和更浅的例子

回答by Sebyddd

user529758's solution in Swift:

user529758 在 Swift 中的解决方案:

Darker color:

颜色较深:

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

Lighter color:

较浅的颜色:

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

回答by Martin R

If you convert the RGB color to the HSL color modelthen you can vary the L = lightness component from L = 0.0 (black) over L = 0.5 (natural color) to L = 1.0 (white) . UIColorcannot handle HSL directly, but there are formula for converting RGB <-> HSL.

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

回答by Terminus

None of the solutions posted quiteworked for all colours and shades, but then I stumbled across this librarywhich provides a set of very well implemented extensions to UIColor.

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

Specifically it has a lighten function as part of its HSL implementation: (UIColor *)lighten:(CGFloat)amount- which works perfectly.

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

回答by Hemang

Sebydddsolution as an extension:

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

Usage:

用法:

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

回答by Jeehut

All other answers in this thread use either the RGB color systemor simply change the hue or brightness value of the HSB system. As explained in detail in this great blog postthe correctway of making a color lighter or darker is to change its luminancevalue. None of the other answers does that. If you want to do it right, then use my solutionor write your ownafter reading the blog post.

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



Unfortunately it's quite a hassleto change any of the attributes of a UIColor by default. Also Apple doesn't even support any LAB-based color space like HCL in the UIColorclass (the Lin LAB is the luminancevalue we are looking for).

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

Using HandyUIKit(install it via Carthage) adds support for HCLand makes your life a lot easier:

使用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)

There is also an option to apply a relative change(recommended):

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

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

Note that HandyUIKit also adds some other handy UI featuresinto your project – checkout its README on GitHubfor more details.

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

I hope it helps!

我希望它有帮助!

回答by Justin Levi Winter

UIColor extension and fixing lighterColorForColor

UIColor 扩展和修复 lightColorForColor

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