Как преобразовать HSB в шестнадцатеричный в Swift 5

У меня есть цвет со значениями HSB (оттенок, насыщенность, яркость), и я хочу напрямую преобразовать RBG в шестнадцатеричную строку. Как я могу это сделать? Есть ли подход без использования API-интерфейсов UIColor, я бы хотел реализовать свою собственную функцию. Например:

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

        return hex // For example "#02AAFE"
    }

person Difeng Chen    schedule 13.07.2020    source источник
comment
ТАК Я думаю, результат должен быть RGB   -  person Leo Dabus    schedule 13.07.2020
comment
Привет @LeoDabus, я обновил вопрос, да, RGB, но в шестнадцатеричном формате.   -  person Difeng Chen    schedule 13.07.2020


Ответы (1)


Вы можете использовать инициализатор UIColor для создания UIColor, а затем извлечь цвета rgb с помощью метода UIColor getRed. Затем вам просто нужно умножить значение компонентов на 255 и создать из них шестнадцатеричное представление с помощью инициализатора системы счисления:

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

Теперь, если вы действительно хотите избежать использования UIColor API, вы можете использовать этот сообщение в качестве ссылки для преобразования из HSB в 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
person Leo Dabus    schedule 13.07.2020