0

I have a Color with HSB(Hue, Saturation, Brightness) values, and I want the convert RBG into a Hexadecimal string directly. How can I do that? Is there an approach without using the UIColor APIs, I'd like to implement my own function Like:

    func toHex(h: CGFloat, s: CGFloat, b: CGFloat) -> String {
        var hex: String
        //conversion

        return hex // For example "#02AAFE"
    }
Difeng Chen
  • 103
  • 7

1 Answers1

0

You can use UIColor initializer to create a UIColor, then extract the rgb colors using UIColor getRed method. Then you just need to multiply the components value by 255 and create an hexa representation from them using string radix initializer:

extension UIColor {
    var rgb: (red: CGFloat, green: CGFloat, blue: CGFloat)? {
        var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0
        guard getRed(&r, green: &g, blue: &b, alpha: nil) else { return nil }
        return (r,g,b)
    }
    var hexa: String? {
        guard let (r,g,b) = rgb else { return nil }
        return "#" + UInt8(r*255).hexa + UInt8(g*255).hexa + UInt8(b*255).hexa
    }
}

extension UInt8 {
    var hexa: String {
        let value = String(self, radix: 16, uppercase: true)
        return (self < 16 ? "0": "") + value
    }
}

let red = UIColor(hue: 1, saturation: 1, brightness: 1, alpha: 1)
let white = UIColor(hue: 1, saturation: 0, brightness: 1, alpha: 1)
let black = UIColor(hue: 1, saturation: 0, brightness: 0, alpha: 1)
red.hexa    // "#FF0000" red
white.hexa  // "#ffffff" white
black.hexa  // "#000000" black

Now if you really want avoid using UIColor api you can use this post as a reference to convert from HSB to RGB:

func toHex<F: BinaryFloatingPoint>(h: F, s: F, b: F) -> String {
    var red, green, blue, i, f, p, q, t: F
    i = (h * 6).rounded(.down)
    f = h * 6 - i
    p = b * (1 - s)
    q = b * (1 - f * s)
    t = b * (1 - (1 - f) * s)
    switch h * 360 {
    case 0..<60, 360: red = b; green = t; blue = p
    case 60..<120: red = q; green = b; blue = p
    case 120..<180: red = p; green = b; blue = t
    case 180..<240: red = p; green = q; blue = b
    case 240..<300: red = t; green = p; blue = b
    case 300..<360: red = b; green = p; blue = q
    default: fatalError()
    return "#" + UInt8(red * 255).hexa + UInt8(green * 255).hexa + UInt8(blue * 255).hexa
}

toHex(h: 1, s: 1, b: 1)         // "#FF0000" red
toHex(h: 1, s: 0, b: 1)         // "#FFFFFF" white
toHex(h: 1, s: 0, b: 0)         // "#000000" black
toHex(h: 0.8333, s: 1, b: 0.5)  // "#7F007F" purple
Leo Dabus
  • 198,248
  • 51
  • 423
  • 494