6

I am attempting to convert a string containing a color in the Generic RGB color space into UIColor in Swift. For example, a typical string would look like this:

0.121569 0.129412 0.156863 1

Using the color picker in macOS, I discovered that these values are using the Generic RGB color space.

enter image description here

However, when I attempt to convert these values into UIColor, it uses the sRGB color space.

let red = CGFloat((components[0] as NSString).doubleValue)
let green = CGFloat((components[1] as NSString).doubleValue)
let blue = CGFloat((components[2] as NSString).doubleValue)
let alpha = CGFloat((components[3] as NSString).doubleValue)
 
print(UIColor(red: red, green: green, blue: blue, alpha: alpha))
// Log Result: NSCustomColorSpace sRGB IEC61966-2.1 colorspace 0.121569 0.129412 0.156863 1 

Hence, a different color is displayed in my application. I confirmed this by changing the color space in Color Picker to IEC61966-2.1 and it indeed displayed different values:

enter image description here

Any idea how I would convert the Generic RGB values into the correct UIColor values?

EDIT For clarification, I am unable to change the color values in the string into another scheme as I am reading the colors from an external source in an XML file

Community
  • 1
  • 1
Alexander MacLeod
  • 2,026
  • 3
  • 14
  • 22

1 Answers1

9

Color conversion by way of color space is performed at the level of CGColor. Example:

let sp = CGColorSpace(name:CGColorSpace.genericRGBLinear)!
let comps : [CGFloat] = [0.121569, 0.129412, 0.156863, 1]
let c = CGColor(colorSpace: sp, components: comps)!
let sp2 = CGColorSpace(name:CGColorSpace.sRGB)!
let c2 = c.converted(to: sp2, intent: .relativeColorimetric, options: nil)!
let color = UIColor(cgColor: c2)

EDIT I think the premise of your original problem is erroneous. You are trying, it turns out, to use the numbers in an Xcode FontAndColorThemes file. Those numbers are sRGB, not generic RGB.

To prove it, I ran this code:

    let sp = CGColorSpace(name:CGColorSpace.sRGB)!
    let comps : [CGFloat] = [0.0, 0.456, 0.0, 1]
    let c = CGColor(colorSpace: sp, components: comps)!
    let v1 = UIView(frame:CGRect(x: 50, y: 50, width: 50, height: 50))
    v1.backgroundColor = UIColor(cgColor:c)
    self.view.addSubview(v1)

That color is taken from the Default color theme's Comment color. Well, the result is identical to the Comment color, as this screen shot demonstrates:

enter image description here

I get the same answer when I use the "eyedropper" tool as when I simply open the color swatch to read the inspector. And I get the same answer when I use the "eyedropper" tool on Xcode's swatch and on my iOS swatch. This seems to me to prove that these colors were always sRGB.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • 1
    Actually I think there is no need for the conversion; you can wrap `c` in a UIColor directly. – matt May 05 '17 at 16:11
  • 1
    I extended my answer to show that the premise of the question was mistaken. – matt May 05 '17 at 18:10
  • For the default xib color space(Generic RGB) what color space we need to use programmatically to achieve the same color, "genericRGBLinear" color space is not working! – niku Mar 09 '21 at 13:36