如何将 UIColor 转换为 HEX 并在 NSLog 中显示

Posted

技术标签:

【中文标题】如何将 UIColor 转换为 HEX 并在 NSLog 中显示【英文标题】:How to convert UIColor to HEX and display in NSLog 【发布时间】:2014-12-08 01:52:29 【问题描述】:

我已经检查了几个关于如何将 UIColor 代码转换为 HEX 的链接,但是我不确定如何调用该方法以在 NSLog 中显示它们。我没有评论的声誉,所以作为问题发布是我最后的手段。 我希望它在我在日志中运行我的应用程序时显示。

其次,我在哪里输入RGB颜色编号(R = 30,G = 171,B = 13)?我看到所有示例都使用 Array [0], [1], [2] 通常指的是索引位置,那么我在哪里添加颜色值?

我有这个代码:

- (NSString *) hexFromUIColor:(UIColor *)color 

    if (CGColorGetNumberOfComponents(color.CGColor) < 4) 
        const CGFloat *components = CGColorGetComponents(color.CGColor);
        color = [UIColor colorWithRed:components[30] green:components[141] blue:components[13] alpha:components[1]];
    
    if (CGColorSpaceGetModel(CGColorGetColorSpace(color.CGColor)) != kCGColorSpaceModelRGB) 
        return [NSString stringWithFormat:@"#FFFFFF"];
    
    return [NSString stringWithFormat:@"#%02X%02X%02X", (int)((CGColorGetComponents(color.CGColor))[0]*255.0), (int)((CGColorGetComponents(color.CGColor))[1]*255.0), (int)((CGColorGetComponents(color.CGColor))[2]*255.0)];


我检查过的链接:

hex color from uicolor

How to convert HEX RGB color codes to UIColor?

我尝试在 viewDidLoad 中调用该方法,但是如果没有 UIColor,它将无法工作。我相信这很简单。

感谢任何回答的人。

为了在 NSLog 中显示,我在 viewDidLoad 中使用什么代码调用此方法?

【问题讨论】:

在这个 github 项目 github.com/toby4242/UIColor-extensions/tree/master/… 上,有一个名为 hexFromUIColor: 的方法,您只需像 NSString *hexStr = [UIColor hexFromUIColor:[UIColor redColor]]; 一样调用它,只需获取您需要的代码即可。 【参考方案1】:

斯威夫特 5:

func hexStringFromColor(color: UIColor) -> String 
    let components = color.cgColor.components
    let r: CGFloat = components?[0] ?? 0.0
    let g: CGFloat = components?[1] ?? 0.0
    let b: CGFloat = components?[2] ?? 0.0

    let hexString = String.init(format: "#%02lX%02lX%02lX", lroundf(Float(r * 255)), lroundf(Float(g * 255)), lroundf(Float(b * 255)))
    print(hexString)
    return hexString
 

func colorWithHexString(hexString: String) -> UIColor 
    var colorString = hexString.trimmingCharacters(in: .whitespacesAndNewlines)
    colorString = colorString.replacingOccurrences(of: "#", with: "").uppercased()

    print(colorString)
    let alpha: CGFloat = 1.0
    let red: CGFloat = self.colorComponentFrom(colorString: colorString, start: 0, length: 2)
    let green: CGFloat = self.colorComponentFrom(colorString: colorString, start: 2, length: 2)
    let blue: CGFloat = self.colorComponentFrom(colorString: colorString, start: 4, length: 2)

    let color = UIColor(red: red, green: green, blue: blue, alpha: alpha)
    return color


func colorComponentFrom(colorString: String, start: Int, length: Int) -> CGFloat 

    let startIndex = colorString.index(colorString.startIndex, offsetBy: start)
    let endIndex = colorString.index(startIndex, offsetBy: length)
    let subString = colorString[startIndex..<endIndex]
    let fullHexString = length == 2 ? subString : "\(subString)\(subString)"
    var hexComponent: UInt32 = 0

    guard Scanner(string: String(fullHexString)).scanHexInt32(&hexComponent) else 
        return 0
    
    let hexFloat: CGFloat = CGFloat(hexComponent)
    let floatValue: CGFloat = CGFloat(hexFloat / 255.0)
    print(floatValue)
    return floatValue

如何使用

let red =  CGFloat(30.0)
let green =  CGFloat(171.0)
let blue =  CGFloat(13.0)
let alpha =  CGFloat(1.0)

let color = UIColor(red: CGFloat(red/255.0), green: CGFloat(green/255.0), blue: CGFloat(blue / 255.0), alpha: alpha)
let colorCode = self.hexStringFromColor(color: color)
print(colorCode)

let resultColor = self.colorWithHexString(hexString: colorCode)
print(resultColor)

目标-C:

- (NSString *)hexStringFromColor:(UIColor *)color 
    const CGFloat *components = CGColorGetComponents(color.CGColor);

    CGFloat r = components[0];
    CGFloat g = components[1];
    CGFloat b = components[2];

    return [NSString stringWithFormat:@"#%02lX%02lX%02lX",
            lroundf(r * 255),
            lroundf(g * 255),
            lroundf(b * 255)];

获取十六进制码字符串后,调用下面的方法获取UIColor

- (UIColor *) colorWithHexString: (NSString *) hexString

    NSString *colorString = [[hexString stringByReplacingOccurrencesOfString: @"#" withString: @""] uppercaseString];

    NSLog(@"colorString :%@",colorString);
    CGFloat alpha, red, blue, green;

    // #RGB
    alpha = 1.0f;
    red   = [self colorComponentFrom: colorString start: 0 length: 2];
    green = [self colorComponentFrom: colorString start: 2 length: 2];
    blue  = [self colorComponentFrom: colorString start: 4 length: 2];

    return [UIColor colorWithRed: red green: green blue: blue alpha: alpha];



- (CGFloat) colorComponentFrom: (NSString *) string start: (NSUInteger) start length: (NSUInteger) length 
    NSString *substring = [string substringWithRange: NSMakeRange(start, length)];
    NSString *fullHex = length == 2 ? substring : [NSString stringWithFormat: @"%@%@", substring, substring];
    unsigned hexComponent;
    [[NSScanner scannerWithString: fullHex] scanHexInt: &hexComponent];
    return hexComponent / 255.0;

如何使用

// ( R = 30, G = 171, B = 13)? 
CGFloat red = 30.0;
CGFloat green = 171.0;
CGFloat blue = 13.0; 
CGFloat alpha = 255.0
UIColor *color = [UIColor colorWithRed:(red/255.0) green:(green/255.0) blue:(blue/255.0) alpha:(alpha/255.0)];
NSString *colorCode = [self hexStringFromColor:color];
NSLog(@"Color Code: %@", colorCode);

UIColor *resultColor = [self colorWithHexString:colorCode];

【讨论】:

我怎么称呼它,所以它会显示,但它不显示给我。 那么NSLog() 在哪里显示十六进制值到控制台?这并没有回答它只是显示如何转换的问题 你没有理解我的问题,也许我不清楚。在我的 viewDidLoad 方法中,调用它并在日志中显示结果的代码是什么? 做到了。感谢您包含 NSLog。从我这里得到滴答声:-) 此代码不安全,除非您确定要处理 RGBA 或 HSVA 颜色。 (HSVA 会自动映射到 RGBA。)但是尝试使用灰度颜色,您将访问内存超出范围。它还返回一个无效的 alpha 值。我强烈建议 Jeff 在下面回答。【参考方案2】:

最后是与 alpha-component 一起使用并使用右乘数的版本

extension UIColor 
    var hexString: String? 
        var red: CGFloat = 0
        var green: CGFloat = 0
        var blue: CGFloat = 0
        var alpha: CGFloat = 0

        let multiplier = CGFloat(255.999999)

        guard self.getRed(&red, green: &green, blue: &blue, alpha: &alpha) else 
            return nil
        

        if alpha == 1.0 
            return String(
                format: "#%02lX%02lX%02lX",
                Int(red * multiplier),
                Int(green * multiplier),
                Int(blue * multiplier)
            )
        
        else 
            return String(
                format: "#%02lX%02lX%02lX%02lX",
                Int(red * multiplier),
                Int(green * multiplier),
                Int(blue * multiplier),
                Int(alpha * multiplier)
            )
        
    

【讨论】:

我很好奇为什么 255.999999 是正确的乘数,而不是(看似)广泛使用的 255。【参考方案3】:

Kampai 的答案适用于 RGB 颜色,但不适用于单色 (UIColor colorWithWhite:alpha:)。它也不处理 HEX 支持的 alpha。这是 hexStringFromColor 的稍微修改版本:

+ (NSString *)hexStringFromColor:(UIColor *)color

    CGColorSpaceModel colorSpace = CGColorSpaceGetModel(CGColorGetColorSpace(color.CGColor));
    const CGFloat *components = CGColorGetComponents(color.CGColor);

    CGFloat r, g, b, a;

    if (colorSpace == kCGColorSpaceModelMonochrome) 
        r = components[0];
        g = components[0];
        b = components[0];
        a = components[1];
    
    else if (colorSpace == kCGColorSpaceModelRGB) 
        r = components[0];
        g = components[1];
        b = components[2];
        a = components[3];
    

    return [NSString stringWithFormat:@"#%02lX%02lX%02lX%02lX",
            lroundf(r * 255),
            lroundf(g * 255),
            lroundf(b * 255),
            lroundf(a * 255)];

【讨论】:

如何使用colorspace 检查来检测我是否尝试获得单色而不是标准RGB?我只能看到测试时不透明度的变化。谢谢。 没关系,我发现这可以改变单色,也就是灰度:[UIColor colorWithWhite:(0.2125 * red) + (0.7154 * green) + (0.0721 * blue) alpha:alpha];【参考方案4】:

其他 Swift 答案对于 UIColors(如白色)崩溃,其中 CGColor 仅返回 2 个组件。

这是一个没有该问题的 Swift 4 版本,如果需要,还会在字符串末尾返回透明度信息(网络格式)。

颜色首先转换为 sRGB 颜色空间,然后生成 HEX 字符串,即使在灰度或其他颜色空间中也能正常工作。

例如:

白色将返回 #FFFFFF

不透明度为 50% 的白色将返回 #FFFFFF7F

extension UIColor 
    var hexString: String 
        let cgColorInRGB = cgColor.converted(to: CGColorSpace(name: CGColorSpace.sRGB)!, intent: .defaultIntent, options: nil)!
        let colorRef = cgColorInRGB.components
        let r = colorRef?[0] ?? 0
        let g = colorRef?[1] ?? 0
        let b = ((colorRef?.count ?? 0) > 2 ? colorRef?[2] : g) ?? 0
        let a = cgColor.alpha

        var color = String(
            format: "#%02lX%02lX%02lX",
            lroundf(Float(r * 255)),
            lroundf(Float(g * 255)),
            lroundf(Float(b * 255))
        )

        if a < 1 
            color += String(format: "%02lX", lroundf(Float(a * 255)))
        

        return color
    

旧版本

此版本不适用于非 RGB 颜色空间中的某些颜色。

extension UIColor 
    var hexString: String 
        let colorRef = cgColor.components
        let r = colorRef?[0] ?? 0
        let g = colorRef?[1] ?? 0
        let b = ((colorRef?.count ?? 0) > 2 ? colorRef?[2] : g) ?? 0
        let a = cgColor.alpha

        var color = String(
            format: "#%02lX%02lX%02lX",
            lroundf(Float(r * 255)),
            lroundf(Float(g * 255)),
            lroundf(Float(b * 255))
        )

        if a < 1 
            color += String(format: "%02lX", lroundf(Float(a)))
        

        return color
    

【讨论】:

a (alpha) 是从 0 到 1 的浮点值,所以你要做的很多:------- color += String(format: "%02lX", lroundf(Float(a * 255 ))) 刚刚实现了这个 sn-p,它现在非常适合。对颜色还没有弄清楚很多,仍然需要更好地理解它:) 这不适用于黑色,因为组件也会更少。其他解决方案之一可能会解决它 你是绝对正确的@JulianKról!我的代码未能考虑非 RGB 颜色空间。请检查我的更新答案。 我仍然认为它不会成功。测试你得到的黑白颜色,你会看到它是否正确:)【参考方案5】:

在 Swift 中,我只是简单地为 UIColor 创建了一个扩展......

extension UIColor


    var hexString:NSString 
        let colorRef = CGColorGetComponents(self.CGColor)

        let r:CGFloat = colorRef[0]
        let g:CGFloat = colorRef[1]
        let b:CGFloat = colorRef[2]

        return NSString(format: "#%02lX%02lX%02lX", lroundf(Float(r * 255)), lroundf(Float(g * 255)), lroundf(Float(b * 255)))
    

【讨论】:

【参考方案6】:

快捷方式:

extension UIColor 
    var hexString: String 
        cgColor.components![0..<3]
            .map  String(format: "%02lX", Int($0 * 255)) 
            .reduce("#", +)
    

如果您需要带 alpha 的十六进制,只需从代码中删除 [0..&lt;3]

另一种更安全的实现,适用于一种组件颜色(如 UIColor.white、UIColor.black):

    var hexString: String 
        var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0
        getRed(&r, green: &g, blue: &b, alpha: nil)
        return [r, g, b].map  String(format: "%02lX", Int($0 * 255)) .reduce("#", +)
    

【讨论】:

【参考方案7】:

根据 Kampai 的回答,这里是 SwiftUI 版本。

extension Color 
    func hexString() -> String 
        let components = self.cgColor?.components
        let r: CGFloat = components?[0] ?? 0.0
        let g: CGFloat = components?[1] ?? 0.0
        let b: CGFloat = components?[2] ?? 0.0

        let hexString = String.init(format: "#%02lX%02lX%02lX", lroundf(Float(r * 255)), lroundf(Float(g * 255)), lroundf(Float(b * 255)))
        return hexString
    

【讨论】:

【参考方案8】:

已接受答案的 Swift 2 版本。我转换成UIColor 扩展。

extension UIColor 
    var hexString: String 
        let components = CGColorGetComponents(self.CGColor)

        let red = Float(components[0])
        let green = Float(components[1])
        let blue = Float(components[2])
        return String(format: "#%02lX%02lX%02lX", lroundf(red * 255), lroundf(green * 255), lroundf(blue * 255))
    

【讨论】:

【参考方案9】:

如果您需要 android 的颜色,这是正确的顺序。阿尔法先行:

extension UIColor 
    var hexString: String? 
        var red: CGFloat = 0
        var green: CGFloat = 0
        var blue: CGFloat = 0
        var alpha: CGFloat = 0

        let multiplier = CGFloat(255.999999)

        guard self.getRed(&red, green: &green, blue: &blue, alpha: &alpha) else 
            return nil
        

        if alpha == 1.0 
            return String(
                format: "#%02lX%02lX%02lX",
                Int(red * multiplier),
                Int(green * multiplier),
                Int(blue * multiplier)
            )
        
        else 
            return String(
                format: "#%02lX%02lX%02lX%02lX",
                Int(alpha * multiplier),
                Int(red * multiplier),
                Int(green * multiplier),
                Int(blue * multiplier)
            )
        
    

然后调用为:

debugPrint("testColor > ", self.testColor().hexString!)

【讨论】:

【参考方案10】:

swift 2 答案转换为 swift 3

var hexString: String 
    let components = self.cgColor.components

    let red = Float((components?[0])!)
    let green = Float((components?[1])!)
    let blue = Float((components?[2])!)
    return String(format: "#%02lX%02lX%02lX", lroundf(red * 255), lroundf(green * 255), lroundf(blue * 255))

【讨论】:

UIExtendedGrayColorSpace 中的颜色崩溃 - 例如黑色,因为组件数组大小为 2。您不应强制解开组件。【参考方案11】:

处理 Alpha 时的潜在陷阱:十六进制字符串有不同的格式,有些在十六进制字符串的开头有它们的 alpha,而其他格式在结尾有它。根据您的背景,您可能对十六进制字符串的格式有不同的想法。对于 Android 开发人员来说,它可能会以 alpha 开头,而对于 Web 开发人员来说,它可能会在字符串的末尾。 请务必说明十六进制字符串的格式以避免混淆。 Android 十六进制字符串需要在开头有 alpha。因此,当涉及到十六进制字符串(我做过)时,人们可能会陷入陷阱,因此说出预期格式是什么很重要。因此,如果您正在为 ios 和 Android 开发应用程序,那么这个陷阱该怎么办。

链接: https://en.wikipedia.org/wiki/RGBA_color_space 了解为什么十六进制字符串可能以不同方式格式化的详细信息,在某些情况下以 alpha 开头。 Android链接https://developer.android.com/reference/android/graphics/Color.html和https://gist.github.com/lopspower/03fb1cc0ac9f32ef38f4

请注意#AARRGGBB十六进制字符串格式 使用以下代码,使 Alpha 位于字符串的开头。

(注意:如果返回color == null黑色)。

+(NSString*)hexStringFromColor:(UIColor *)color


    CGFloat r = 0, g = 0, b = 0, a = 1;

    if (color) 
        [color getRed:&r green:&g blue:&b alpha:&a];
    

    return [NSString stringWithFormat:@"#%02lX%02lX%02lX%02lX",
            lroundf(a * 255.0),
            lroundf(r * 255.0),
            lroundf(g * 255.0),
            lroundf(b * 255.0)
            ];


【讨论】:

感谢您的回答。您是否有任何证据支持您的说法,即“由于将 alpha 放在末尾而导致颜色错误”?我很想阅读或见证它。我倾向于不同意苹果的以下文档,明确声明 alpha 组件是最后初始化的 - developer.apple.com/documentation/uikit/uicolor/1621931-init 进一步阅读可以在这里找到:developer.apple.com/documentation/uikit/uicolor 我将在进行跨平台开发(iOS 和 Android)时更新我的​​答案,因此将 HEX 字符串称为#AARRGGBB。这是 HEX 字符串可以采用的各种格式的链接。 en.wikipedia.org/wiki/RGBA_color_space App Dev Guy,您的链接指的是 UIColor,您是正确的,最后使用 alpha 变量初始化。但是对于 HEX 字符串,它可能会在开头或结尾使用 alpha 进行格式化,具体取决于所使用的格式。 是的,正确的。然而,问题推断在 NSLog 中显示结果,在这种情况下,它是特定于 iOS 的。自然地以字符串或其他方式显示 alpha 组件,最后这样做是有意义的。也许考虑添加您的链接以支持您的答案,以便其他读者更好地理解您所指的内容:-) en.wikipedia.org/wiki/RGBA_color_space 了解为什么十六进制字符串可能以不同方式格式化的详细信息,在某些情况下以 alpha 开头。 Android 十六进制字符串需要在开头有 alpha。因此,当涉及到十六进制字符串(我做过)时,人们可能会陷入陷阱,因此说出预期格式是什么很重要。因此,如果您要向移动应用程序发送十六进制字符串,请务必说明格式。 Android 链接 developer.android.com/reference/android/graphics/Color.html 和 gist.github.com/lopspower/03fb1cc0ac9f32ef38f4【参考方案12】:

我正在使用这个扩展:(Swift 5.x)如果你将颜色传递为 .white 你会得到 #ffffff

import UIKit
extension UIColor 
    convenience init(hexString: String, alpha: CGFloat = 1.0) 
        let hexString: String = hexString.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
        let scanner = Scanner(string: hexString)
        if (hexString.hasPrefix("#")) 
            scanner.scanLocation = 1
        
        var color: UInt32 = 0
        scanner.scanHexInt32(&color)
        let mask = 0x000000FF
        let r = Int(color >> 16) & mask
        let g = Int(color >> 8) & mask
        let b = Int(color) & mask
        let red   = CGFloat(r) / 255.0
        let green = CGFloat(g) / 255.0
        let blue  = CGFloat(b) / 255.0
        self.init(red:red, green:green, blue:blue, alpha:alpha)
    

    func hexStringFromColor() -> String 
        var r:CGFloat = 0
        var g:CGFloat = 0
        var b:CGFloat = 0
        var a:CGFloat = 0
        getRed(&r, green: &g, blue: &b, alpha: &a)
        let rgb:Int = (Int)(r*255)<<16 | (Int)(g*255)<<8 | (Int)(b*255)<<0
        return String(format:"#%06x", rgb)
    

用法:

let color = UIColor(hexString: "#3f3f3f")
or
color.hexStringFromColor()

【讨论】:

// 'scanLocation' 在 iOS 13.0 中已弃用 // 'scanLocation' 在 iOS 13.0 中已弃用 使用 currentIndex 而不是 scanLocation...我也会更新我的答案。【参考方案13】:

或者你可以使用.hexCode如果使用这个UIColor扩展。

像这样:

extension UIColor 
    var hexCode: String 
        get
            let colorComponents = self.cgColor.components!
            if colorComponents.count < 4 
                return String(format: "%02x%02x%02x", Int(colorComponents[0]*255.0), Int(colorComponents[0]*255.0),Int(colorComponents[0]*255.0)).uppercased()
            
            return String(format: "%02x%02x%02x", Int(colorComponents[0]*255.0), Int(colorComponents[1]*255.0),Int(colorComponents[2]*255.0)).uppercased()
        
    


var myColor: UIColor?
myColor = UIColor(red: 1, blue: 1, green: 1, alpha: 1.0)
print(myColor!.hexCode) // output: 
// if you use API, you can do something like this:
print("#\(myColor!.hexCode)") // output: #FFFFFF

【讨论】:

【参考方案14】:

斯威夫特 5

extension Collection 
    public subscript(safe index: Index) -> Element? 
        return startIndex <= index && index < endIndex ? self[index] : nil
    

extension UIColor 
    var hexString: String 
        let components = cgColor.components
        let r: CGFloat = components?[safe: 0] ?? 0.0
        let g: CGFloat = components?[safe: 1] ?? 0.0
        let b: CGFloat = components?[safe: 2] ?? 0.0

        let hexString = String(format: "#%02lX%02lX%02lX", lroundf(Float(r * 255)), lroundf(Float(g * 255)),
                               lroundf(Float(b * 255)))

        return hexString
    

【讨论】:

【参考方案15】:

SwiftUI

P3 颜色 HEX

extension Color 

    var hex: String 
        guard let colorSpace = CGColorSpace(name: CGColorSpace.displayP3), let color = UIColor(self).cgColor.converted(to: colorSpace, intent: .defaultIntent, options: nil),
          let components = color.components, 3 <= components.count else  return "" 

        return String(format: "#%02lX%02lX%02lX%02lX", lroundf(Float(components[0] * 255)), lroundf(Float(components[1] * 255)), lroundf(Float(components[2] * 255)), lroundf(Float(components[3] * 255)))
     

【讨论】:

以上是关于如何将 UIColor 转换为 HEX 并在 NSLog 中显示的主要内容,如果未能解决你的问题,请参考以下文章

objective-C和C --- 《位运算》的使用之二进制颜色的转换

swift-3.0 将HexColor转变为UIColor的方法

ios 怎么把颜色转为16进制

如何将 UIColor 转换为 SwiftUI 的颜色

如何为Android转换器中的MvxColor指定Hex或RGB颜色

如何将 UIColor 转换为十六进制字符串?