web-dev-qa-db-ja.com

UIColorからわずかに明るい色と暗い色を取得

UIColorをグラデーションに変換できるようにしたいと考えていました。これを行うつもりは、Core Graphicsを使用してグラデーションを描画することです。私がやろうとしているのは、色をつけることです、と言うことができます:

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

そして、いくつかの色合いがより暗く、いくつかの色合いがより明るいUIColorを取得します。誰もこれを行う方法を知っていますか?ありがとうございました。

140
CoreCode
- (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のアイデアから、定数値を加算または減算する代わりに、色を適切に暗くまたは明るくすることをお勧めします。 @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
274
user529758

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ソリューションは色をブリグネススケールのエッジに近づけます-基本的に黒で始まり、純粋な色で終わります...

基本的に、明るさ(値)は色を黒に近づけたり近づけたりしますが、彩度では色を白に近づけたり近づけたりします...

ここに見られるように:

HSV color graph

したがって、色を実際に明るくする(つまり、白に近づける...)ための解決策は、彩度の値より小さいにすることです。

- (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;
}
53
Aviel Gross

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

サンプル :

enter image description here

37
CryingHippo

RGBで同じ結果を出したかっただけです

  • 白い背景の上にアルファx%の色を配置して明るくします
  • 黒を背景にアルファx%の色を配置して暗くする

これは、グラデーションサイズのx%でグラデーション「color to white」または「color to black」で色を選択するのと同じ結果AFAIKを提供します。

そのために、数学は簡単です:

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

ここにいくつかの色の例があります

Examples Darker and Lighter

23
FredericP

Swiftでのuser529758のソリューション:

より暗い色:

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

RGBカラーを HSLカラーモデル に変換すると、L =明度成分をL = 0.0(黒)からL = 0.5(自然色)にかけてL = 1.0(白)に変えることができます。 UIColorはHSLを直接処理できませんが、RGB <-> HSLを変換するための式があります。

13
Martin R

投稿されたソリューションはどれもquiteはすべての色と色合いで機能しませんでしたが、偶然見つけました このライブラリ UIColorの拡張機能が非常によく実装されています。

具体的には、HSL実装の一部として(UIColor *)lighten:(CGFloat)amount-完全に機能する軽量化機能があります。

6
Terminus

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()
5
Hemang

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

このスレッドの他のすべての回答では、RGBカラーシステムを使用するか、単にHSBシステムの色相または輝度値を変更します。 この素晴らしいブログ記事 で詳細に説明されているように、色を明るくしたり暗くしたりする正しい方法は、luminance値を変更することです。それ以外の答えはありません。正しく実行したい場合は、ブログの投稿を読んでからソリューションを使用または独自に作成します。


残念ながら、UIColor デフォルトでの属性を変更するのはかなり面倒ですです。また、Appleは、UIColorクラスのHCLのようなLABベースの色空間もサポートしていません(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)

相対変更を適用するオプションもあります(推奨):

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

HandyUIKitがその他の便利なUI機能をプロジェクトに追加することに注意してください。詳細については、 README on GitHub をご覧ください。

私はそれが役立つことを願っています!

2
Dschee

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を使用する必要があります。

2

あなたが何らかの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];

それはあなたが探している種類の効果ですか?

1
ravron

iOS 12のSwift 4.xでXcode 10でテスト済み

UIColorとしての色から始めて、(CGFloatとして)暗化要素を選択します

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

タイプCGColorには、オプションの値componentsがあります。この値は、色をRGBAに分解します(値が0〜1のCGFloat配列として)。その後、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で除算され、色は以前の半分の濃さになりました。アルファ値は同じままでしたが、RGBではなくアルファ値に暗化係数を適用することもできます。

1
Microbob

理想的には、関数はUIColor+Brightness.Swiftと呼ばれるUIColor拡張内にカプセル化され、輝度を構成可能にする必要があります-以下の例を参照してください:

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

}
0
Zorayr

色の変化量を制御できる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;
}
0
Blago

A @Sebyddd answer:に基づくSwift拡張子

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
Balázs Vincze

暗い色の場合、これが最も簡単です。theColor= [theColor shadowWithLevel:s]; //s:0.0から1.0

0
Jiulong Zhao

ステータス値に基づいて色付きのセルをレンダリングします。

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にも機能します。 UIColorNSColorに置き換えるだけです。

0
Besi