Search code examples
iosswiftuicoloruicolorpickerviewcontroller

Convert Display P3 to eSRGB by hex color in iOS swift?


I'm using UIColorPickerViewController. When I use Sliders section, default value is display p3 like below an image.

enter image description here

My app is using UIExtendedSRGBColorSpace. So I need to convert to UIExtendedSRGBColorSpace. When I convert from Display P3 to eSRGB, it returns UIExtendedSRGBColorSpace -0.511642 1.01827 -0.310624 1.

convert code is here.

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

func updateFromP3ToExtendedsRGB() -> UIColor?
    {
        guard self.cgColor.colorSpace?.name == CGColorSpace.displayP3 else { return nil }
        let convertColor = self.cgColor.converted(to: .extendedSRGB, intent: .relativeColorimetric, options: nil)
        if let convertCGColor = convertColor
        {
            return UIColor(cgColor: convertCGColor)
        }
        
        return nil
    }

I got negative value. Here is the problem.

I need to save color with hex code. When I changed to hex code of converted color, it turns different color like yellow color ffffffb1.

enter image description here

here is code to converting hex code.

func toHexString() -> 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 argb:Int = (Int)(a*255)<<24 | (Int)(r*255)<<16 | (Int)(g*255)<<8 | (Int)(b*255)<<0
        return NSString(format:"%06x", argb) as String
    }

So, my question is how to convert from display p3 to eSRGB by hex string?

enter image description here


Solution

  • If you convert from UIColor, hex value always is sRGB colorspace. You should convert from CGColor. Apple UIColor

    
    extension CGColor {
        func toHex() -> String? {
            guard let components = components else { return nil }
            
            if components.count == 2 {
                let value = components[0]
                let alpha = components[1]
                return String(format: "#%02lX%02lX%02lX%02lX", lroundf(Float(alpha*255)), lroundf(Float(value*255)), lroundf(Float(value*255)), lroundf(Float(value*255)))
            }
            
            guard components.count == 4 else { return nil }
            
            let red   = components[0]
            let green = components[1]
            let blue  = components[2]
            let alpa  = components[3]
            
            let hexString = String(format: "#%02lX%02lX%02lX%02lX",lroundf(Float(alpa*255)), lroundf(Float(red*255)), lroundf(Float(green*255)), lroundf(Float(blue*255)))
            
            return hexString
        }
    }
    
    
    extension UIColor {
        func toHexString() -> String {
            cgColor.toHex() ?? ""
        }
        
        func toDisplayP3HexString() -> String {
            guard let displayP3Color = self.cgColor.converted(to: CGColorSpace(name: CGColorSpace.displayP3)!, intent: .defaultIntent, options: nil) else {
                return ""
            }
            return displayP3Color.toHex() ?? ""
        }
    }