Search code examples
iosswiftswift5uicolor

Converting from UIExtendedSRGBColorSpace to Hex


I'm using a framework that outputs colour in the UIExtendedSRGBColorSpace format. I need to display a six character hex value for this output colour to the user and for a backend application that only accepts six-character hex codes. I've tried numerous conversion methods but they all seem to result in odd hex values. For example, getting an output UIExtendedSRGBColorSpace 0.276088 -0.0525 1.05 1 and using an extension like this (which i've used successfully many times before) results in 46FFFFFFFFFFFFFFF310C. There are no issues with simply applying the UIExtendedSRGBColorSpace output as a background colour on a button/view, but its getting a hex value of the colour that is the problem.

It would be fine if any solution to this leads to some form of loss in colour accuracy, as long as i'm able to get a vaguely similar hex code. I'm very new to programming and have spent quite some time trying to understand this with no luck, so appreciate any help!


Solution

  • You can convert your UIColor to CGColor and convert from eRGB to sRGB. Note that once you convert it to standard RGB you can't convert back to extended RGB:

    extension CGColorSpace {
        static let sRGB = CGColorSpace(name: CGColorSpace.sRGB)!
        static let extendedSRGB = CGColorSpace(name: CGColorSpace.extendedSRGB)!
    }
    

    extension CGColor {
        var color: UIColor { .init(cgColor: self) }
    }
    

    extension UIColor {
        var extendedSRGB2sRGB: UIColor? {
            guard let components = cgColor.components else { return nil }
            return CGColor(colorSpace: .extendedSRGB, components: components)?
                .converted(to: .sRGB, intent: .relativeColorimetric, options: nil)?.color
        }
    }
    

    Playground testing:

    let extendedSRGB = UIColor(red: 0.276088, green: -0.0525, blue: 1.05, alpha: 1)
    let sRGB = extendedSRGB.extendedSRGB2sRGB  // r 0.276 g 0.0 b 1.0 a 1.0