I would like to implement a search where images can be filtered by colors. My image-model contains up to 10 UIColors that occur in that specific image, now I would like to have a filter with e.g. blue, green, red, yellow. How can I check (with a specified tolerance) if that specific image contains blue/green/...?
I tried with CIE94-difference, but that doesn't not match the perceived similarity by the human eye. I also tried to compare the hue and saturation value, but that doesn't work either.
As an example:
`#23567E` should be blue
`#7A010B` should be red as well as `#FD4E57`
`#0F8801` should be found for green as well as `#85FE97`
I have a specific instance of UIColor
, e.g.
[UIColor colorWithRed:0.137 green:0.337 blue:0.494 alpha:1] // #23567E
this should be "equal" to .blue
[UIColor colorWithRed:0.478 green:0.00392 blue:0.0431 alpha:1] // #7A010B
should be "equal" to .red
and so on...
If your intend is only to check which color is your UIColor you can simply get your HSB color components and compare its hue value:
You will need a helper to convert your hexa string to UIColor
extension UIColor {
convenience init?(hexString: String) {
var chars = Array(hexString.hasPrefix("#") ? hexString.dropFirst() : hexString[...])
switch chars.count {
case 3: chars = chars.flatMap { [$0, $0] }; fallthrough
case 6: chars = ["F","F"] + chars
case 8: break
default: return nil
}
self.init(red: .init(strtoul(String(chars[2...3]), nil, 16)) / 255,
green: .init(strtoul(String(chars[4...5]), nil, 16)) / 255,
blue: .init(strtoul(String(chars[6...7]), nil, 16)) / 255,
alpha: .init(strtoul(String(chars[0...1]), nil, 16)) / 255)
}
}
And some helpers to extract its hue component:
extension UIColor {
enum Color {
case red, orange, yellow, yellowGreen, green, greenCyan, cyan, cyanBlue, blue, blueMagenta, magenta, magentaRed
}
func color(tolerance: Int = 15) -> Color? {
precondition(0...15 ~= tolerance)
guard let hsb = hsb else { return nil }
if hsb.saturation == 0 { return nil }
if hsb.brightness == 0 { return nil }
let hue = Int(hsb.hue * 360)
switch hue {
case 0 ... tolerance: return .red
case 30 - tolerance ... 30 + tolerance: return .orange
case 60 - tolerance ... 60 + tolerance: return .yellow
case 90 - tolerance ... 90 + tolerance: return .yellowGreen
case 120 - tolerance ... 120 + tolerance: return .green
case 150 - tolerance ... 150 + tolerance: return .greenCyan
case 180 - tolerance ... 180 + tolerance: return .cyan
case 210 - tolerance ... 210 + tolerance: return .cyanBlue
case 240 - tolerance ... 240 + tolerance: return .blue
case 270 - tolerance ... 270 + tolerance: return .blueMagenta
case 300 - tolerance ... 300 + tolerance: return .magenta
case 330 - tolerance ... 330 + tolerance: return .magentaRed
case 360 - tolerance ... 360 : return .red
default: break
}
return nil
}
var hsb: (hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat)? {
var hue: CGFloat = 0, saturation: CGFloat = 0, brightness: CGFloat = 0, alpha: CGFloat = 0
guard getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) else {
return nil
}
return (hue, saturation, brightness, alpha)
}
}
Playground testing:
let blue: UIColor.Color? = UIColor(hexString: "#23567E").color() // r 0.137 g 0.337 b 0.494 a 1.0
let red1: UIColor.Color? = UIColor(hexString: "#7A010B").color() // r 0.478 g 0.004 b 0.043 a 1.0
let red2: UIColor.Color? = UIColor(hexString: "#FD4E57").color() // r 0.992 g 0.306 b 0.341 a 1.0
let green1: UIColor.Color? = UIColor(hexString: "#0F8801").color() // r 0.059 g 0.533 b 0.004 a 1.0
let green2: UIColor.Color? = UIColor(hexString: "#85FE97").color() // t 0.522 g 0.996 b 0.592 a 1.0
UIColor(hue: 90/360, saturation: 0, brightness: 1, alpha: 1).color() // nil
UIColor(hue: 90/360, saturation: 1, brightness: 0, alpha: 1).color() // nil
UIColor(hue: 90/360, saturation: 0, brightness: 0, alpha: 1).color() // nil
UIColor.black.color() // nil
UIColor.white.color() // nil
UIColor.lightGray.color() // nil
UIColor.darkGray.color() // nil
UIColor.red.color() // 0...15 && 346...360 = red
UIColor.orange.color() // 16...45 = orange
UIColor.yellow.color() // 46...75 = yellow
UIColor(hue: 90/360, saturation: 1, brightness: 1, alpha: 1).color() // 76...105 yellowGreen
UIColor.green.color() // 106...135 = green
UIColor(hue: 150/360, saturation: 1, brightness: 1, alpha: 1).color() // 136...165 greenCyan
UIColor.cyan.color() // 166...195 = cyan
UIColor(hue: 210/360, saturation: 1, brightness: 1, alpha: 1).color() // 196...225 cyanBlue
UIColor.blue.color() // 226...255 = blue
UIColor(hue: 270/360, saturation: 1, brightness: 1, alpha: 1).color() // 256...285 blueMagenta
UIColor.magenta.color() // 286...315 = magenta
UIColor(hue: 330/360, saturation: 1, brightness: 1, alpha: 1).color() // 316...345 = magentaRed
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With