Change UIColors to RGB and HSB colors

One dilemma you’ll find when working with colors is switching between color systems. There’s two you’ll most often be using: the Red-Green-Blue or RGB and Hue-Saturation-Brightness or HSB. Download the Exercise file and run. It will give you the HSB value, but what if you want a RGB Value for that color? What if you want the values for any UIColor? Let’s look at some special methods for that. 

In the exercise files, go to  ColorModel.swift and the ColorEntry class. I’ll add some methods here to do all this.  

I stubbed a method  rgbString here for  you with a few variables: 

func rgbString()->String{
        var rgb = ""
        var red:CGFloat = 0
        var green:CGFloat = 0
        var blue:CGFloat = 0
        var alpha:CGFloat = 0
        return rgb

There’s a UIColor method getRed that gets you the red green, blue and alpha components of a color.  It works a bit differently than most methods though. Its parameters are unsafe mutable pointers, and it returns a Bool if it was successful. I’ll put it in an if statement to catch any errors  like this: 

if !color.getRed(&red, green: &green, blue: &blue, alpha: &alpha){
           
        }

Unsafe pointers work a little backward. You put a strong  pass-through variable for the parameter prefixed by the ampersand (&). I invert the bool here so I’ll deal with error conditions in the if clause. I’ll just return the blank rgb value in this case, which

if !color.getRed(&red, green: &green, blue: &blue, alpha: &alpha){
return rgb
}

If successful, I’ll make a string to return the RGB color as a String

rgb = String(format:"R:%04.3f G:%04.3f B:%04.3f",red,green,blue)

I can do the same  with HSB Colors wit the getHue method. I already have properties for this in my model, I just need to add the alpha. The code for this is very similar. 

func hsbString()->String{
        var hsb = ""
        var alpha:CGFloat = 0
        if !color.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha){
            return hsb
        }
        
        hsb = String(format:"H:%04.3f S:%04.3f B:%04.3f",hue,saturation,brightness)
        return hsb
    }

I can now set my color name by these two strings. I’ll make an initializer that creates the name from the strings: 

init(color:UIColor){
        self.color = color
        self.name = hsbString() + "\n" + rgbString()
    }

I’ll also change the name on my first initializer to include both: 

init(name:String,color:UIColor){
        self.color = color
        self.name = name + "\n" + hsbString() + "\n" + rgbString()
    }

I don’t need to use the first initializer in the hues method of color model, I can use the second, so I’ll change that: 

//let name = String(format:"H:%04.3f S:1.0 B:1.0 ",hueValue)
let colorEntry = ColorEntry(color: color)

Run the app. You’ll see the table has changed. When you select a color, both values show up. 

You can use these methods for testing colors in many places, including pixels in images. While a little clunky with he unsafe mutable pointers, this is a relatively easy way to get get colors from one system to another. 

The (not so) Whole Code

I’ve been using the same code for the last few weeks. You can go to the last lesson to get everything but the changes made to ColorModel.swift, which is below. You can also download the completed project from Github.

//
//  ColorModel.swift
//  ColorPicker
//
//
//  An exercise file for iOS Development Tips Weekly
//  by Steven Lipton (C)2018, All rights reserved
//  For videos go to http://bit.ly/TipsLinkedInLearning
//  For code go to http://bit.ly/AppPieGithub
//

import UIKit

class ColorEntry{
    var name:String = ""
    var color:UIColor
    var hue:CGFloat = 0.0
    var brightness:CGFloat = 0.5
    var saturation:CGFloat = 1.0
    
    init(name:String,color:UIColor){
        self.color = color
        self.name = name + "\n" + hsbString() + "\n" + rgbString()
    }
    
    init(color:UIColor){
        self.color = color
        self.name = hsbString() + "\n" + rgbString()
    }
    
    
    func rgbString()->String{
        var rgb = ""
        var red:CGFloat = 0
        var green:CGFloat = 0
        var blue:CGFloat = 0
        var alpha:CGFloat = 0
        
        if !color.getRed(&red, green: &green, blue: &blue, alpha: &alpha){
            return rgb
        }
        
        rgb = String(format:"R:%04.3f G:%04.3f B:%04.3f",red,green,blue)
        return rgb
    }
    
    func hsbString()->String{
        var hsb = ""
        var alpha:CGFloat = 0
        if !color.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha){
            return hsb
        }
        
        hsb = String(format:"H:%04.3f S:%04.3f B:%04.3f",hue,saturation,brightness)
        return hsb
    }
    
}


class ColorModel{
    var colors = [ColorEntry]()
    init(){
        colors = []
    }
    func hues(count:Int)->[ColorEntry]{
        colors = []
        if count <= 0 {return colors}
        for hue in 0...count{
            let hueValue = CGFloat(hue)/CGFloat(count)
            let color = UIColor(hue: hueValue, saturation: 1.0, brightness: 1.0, alpha: 1.0)
            //let name = String(format:"H:%04.3f S:1.0 B:1.0 ",hueValue)
            let colorEntry = ColorEntry(color: color)
            colors += [colorEntry]
        }
        return colors
    }
    
    func lightnessScale(hue:UIColor,count:Int){
        
    }
    
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: