如何将UIColor转换为十六进制(web颜色文本字符串)?

7
有没有简单的方法将 UIColor 转换为十六进制值?或者我们需要使用 CGColorGetComponents 获取 RGB 组件,然后从那里计算出来?
例如: CGColorGetComponents(color.CGColor)[0] * 256 ?
6个回答

10

我还需要将UIColor转换为其十六进制组件。

正如lewiguez指出的那样,在github上有一个非常好的类别可以完成所有这些工作。

但是因为我想学习它的实现方式,所以我自己实现了一个简单的RGB颜色转换方法。

+ (NSString*)colorToWeb:(UIColor*)color
{
    NSString *webColor = nil;

    // This method only works for RGB colors
    if (color &&
        CGColorGetNumberOfComponents(color.CGColor) == 4)
    {
        // Get the red, green and blue components
        const CGFloat *components = CGColorGetComponents(color.CGColor);

        // These components range from 0.0 till 1.0 and need to be converted to 0 till 255
        CGFloat red, green, blue;
        red = roundf(components[0] * 255.0);
        green = roundf(components[1] * 255.0);
        blue = roundf(components[2] * 255.0);

        // Convert with %02x (use 02 to always get two chars)
        webColor = [[NSString alloc]initWithFormat:@"%02x%02x%02x", (int)red, (int)green, (int)blue];
    }

    return webColor;
}

欢迎提供所有反馈意见!


7

我建议使用Erica Sadun的UIColor类别。它包括很多免费的功能,包括十六进制表示法。使用起来非常简单,只需将其添加到您正在使用的任何类头文件中,或者将其添加到预编译头文件中以获得最大的灵活性。 如果要添加到预编译头文件中,请类似于以下内容进行操作:

#ifdef __OBJC__
    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    #import "UIColor-Expanded.h"
#endif

您可以这样使用它:NSLog(@"%@", [myColor hexStringFromColor]); UIColor类别的GitHub链接:https://github.com/erica/uicolor-utilities ArsTechnica关于此的文章:http://arstechnica.com/apple/guides/2009/02/iphone-development-accessing-uicolor-components.ars

2

除了广泛使用的基于字符串的解决方案外,这里提供一种基于十六进制(整数)的解决方案。用法:

UIColor* color = lf_rgb(0x120aef);
log(@"color %.6x", color.hex_rgb);

你将得到“颜色120aef”。我将把这些代码放在https://github.com/superarts/LCategory中,或者您也可以将其复制粘贴到自己的代码库中:

#define lf_rgb(rgbValue)    [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]

@interface UIColor (lc_rgb)
- (NSInteger)hex_rgb;
@end

@implementation UIColor (lc_rgb)
- (NSInteger)hex_rgb
{
    CGFloat r, g, b, a;
    BOOL result = [self getRed:&r green:&g blue:&b alpha:&a];
    //  log(@"rgba: %f, %f, %f, %f", r * 255, g * 255, b * 255, a * 255);
    if ((result == NO) || (a != 1.0f))
        return -1;
    return 
        (NSInteger)(r * 255) * 256 * 256 + 
        (NSInteger)(g * 255) * 256 +
        (NSInteger)(b * 255) * 1;
}
@end

1

据我所知,目前没有内置的解决方案。
但请注意,您应该乘以255而不是256

获取十六进制表示法是一项简单的任务,因此您不会遇到太多问题来手动构建字符串。

NSLog(@"%X%X%X", redInteger, greenInteger, blueInteger);

我认为这是一个聪明的做法。由于组件返回一个浮点数,你如何精确地将其转换为整数呢?例如,对于一种紫色颜色:UIDeviceRGBColorSpace 0.548638 0.554697 1 1 - fes
你可以通过强制转换或四舍五入的方式得到整数,测试RGB 0.548638 0.554697 1,截断、四舍五入,每次给我相同的紫色。 - user971401
你能给我一个截断和四舍五入的例子吗?也许我四舍五入得太高了,但我总是得到1,%X%X%X出现为111。 - fes
@fes - (NSUInteger)(0.548638 * 255.0) == 139 - user971401

1

这是我用Swift 3实现的方法:

extension UIColor {
    var hex:String{
        get{
            var red:CGFloat = 0
            var blue:CGFloat = 0
            var green:CGFloat = 0
            var alpha:CGFloat = 0

            self.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
            let rgb:Int = (Int)(red*255)<<16 | (Int)(green*255)<<8 | (Int)(blue*255)<<0
            return String.localizedStringWithFormat("#%06x", rgb)
        }
    }
}

或者您可以将其制作为一个方法。我只是喜欢color.hex的外观,而不是color.hex()

0
这是一个Swift 5的解决方案,作为UIColor的扩展,将UIColor对象转换为RGB(#RRGGBB)格式或RGBA(#RRGGBBAA)格式的十六进制颜色字符串,并且还可以使用任一格式创建UIColor,提供alpha参数选项,以#RRGGBB形式作为非默认值1.0的alpha。
我从@boidkan的答案开始,然后在S.O.上搜索其他解决方案,然后对它们进行了优化和改进,得到了一个我可以接受的解决方案,并在playground中进行了测试。
/* Returns UIColor as "#RRGGBB" (hex string) */
var hexRGB : String {
    func comp(_ value: CGFloat, _ byteShift: Int = 0) -> Int { return Int(value * 0xff) << (byteShift * 8) }
    var r = CGFloat(0), b = CGFloat(0), g = CGFloat(0), a = CGFloat(0)
    getRed(&r, green: &g, blue: &b, alpha: &a)
    return String(format: "#%6.6X", comp(r, 2) | comp(g, 1) | comp(b))
}

/* Returns UIColor as "#RRGGBBAA" (hex string) */
var hexRGBA : String {
    func comp(_ value: CGFloat, _ byteShift: Int = 0) -> Int { return Int(value * 0xff) << (byteShift * 8) }
    var r = CGFloat(0), b = CGFloat(0), g = CGFloat(0), a = CGFloat(0)
    getRed(&r, green: &g, blue: &b, alpha: &a)
    return String(format: "#%8.8X", comp(r, 3) | comp(g, 2) | comp(b, 1) | comp(a))
}

/*
 * Returns UIColor object given input of the one of the following formats, where:
 *
 *       RR = Red component as hex value    00-FF
 *       GG = Green component as hex value  00-FF
 *       BB = Blue component as hex value   00-FF
 *       AA = Alpha componenet as hex value 00-FF
 *        a = Alpha component as 0.00 - 1.00 (a is optional, defaults to 1.0)
 *
 *       ("RRGGBB"[, a]),   ("#RRGGBB"[, a]), ("RRGGBBAA"), or ("#RRGGBBA")
 */
convenience init(hexRGBA: String, alpha: CGFloat = 1.0) {
    let cleanHex = hexRGBA.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
                          .replacingOccurrences(of: #"[^0-9a-fA-F]"#, with: "", options: .regularExpression)

    assert(cleanHex.count == 6 || cleanHex.count == 8, "Bad RGB/RGBA value")
    
    var rgbIntValue: UInt64 = 0
    Scanner(string:cleanHex).scanHexInt64(&rgbIntValue)
    let hh1 = CGFloat( Double((rgbIntValue & 0xff000000) >> 24)  / 255.0)
    let hh2 = CGFloat( Double((rgbIntValue & 0x00ff0000) >> 16)  / 255.0)
    let hh3 = CGFloat( Double((rgbIntValue & 0x0000ff00) >> 8)   / 255.0)
    let hh4 = CGFloat( Double((rgbIntValue & 0x000000ff)         / 255.0)
    if (cleanHex.count == 8) {
        self.init(red:  hh1, green: hh2, blue: hh3, alpha: hh4)
        return
    }
    self.init(red: hh2, green: hh3, blue: hh4, alpha: alpha) /* RGB + A */
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接