Проверьте, является ли цвет синим (i sh), красным (i sh), зеленым (i sh), - PullRequest
6 голосов
/ 04 февраля 2020

Я хотел бы реализовать поиск, где изображения могут быть отфильтрованы по цветам. Моя модель изображения содержит до 10 цветов UIC, которые встречаются в этом конкретном изображении c, теперь я хотел бы иметь фильтр, например, синий, зеленый, красный, желтый. Как я могу проверить (с указанным допуском), содержит ли это указанное c изображение синий / зеленый /...?

Я пробовал с CIE94-разницей, но это не соответствует воспринимаемому сходству человеческий глаз. Я также пытался сравнить значение оттенка и насыщенности, но это тоже не работает.

Как пример:

`#23567E` should be blue
`#7A010B` should be red as well as `#FD4E57`
`#0F8801` should be found for green as well as `#85FE97`

У меня есть указанный c экземпляр UIColor Например,

[UIColor colorWithRed:0.137 green:0.337 blue:0.494 alpha:1] // #23567E

это должно быть «равно» .blue

[UIColor colorWithRed:0.478 green:0.00392 blue:0.0431 alpha:1] // #7A010B

должно быть «равно» .red

и так далее ...

Ответы [ 3 ]

7 голосов
/ 04 февраля 2020

Если вы намерены только проверить, какой цвет соответствует вашему UIColor, вы можете просто получить цветовые компоненты HSB и сравнить его значение оттенка:

Вам понадобится помощник для преобразования вашей строки hexa в 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)
    }
}

И некоторые помощники, чтобы извлечь его компонент оттенка:

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)
    }
}

Тестирование игровой площадки:

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
2 голосов
/ 07 февраля 2020

UIColor CGColor имеет свойство components, которое возвращает массив значений красного, зеленого, синего и альфа в виде [CGFloat]?

Это работает в соответствии с вашими требованиями Цвета на основе RGB. Работает и с другими цветами, но будет возвращать другой набор значений вместо r, g, b, значений

Протестировано с предоставленными вами цветами:

let blueShade = UIColor.init(hexString: "23567E")
print(blueShade.cgColor.components)
//prints Optional([0.13725490196078433, 0.33725490196078434, 0.49411764705882355, 1.0])

let redShade = UIColor.init(hexString: "7A010B")
print(redShade.cgColor.components)
//prints Optional([0.47843137254901963, 0.00392156862745098, 0.043137254901960784, 1.0])

let greenShade = UIColor.init(hexString: "0F8801")
print(greenShade.cgColor.components)
//prints Optional([0.058823529411764705, 0.5333333333333333, 0.00392156862745098, 1.0])

Это то, что вы ищете?

0 голосов
/ 07 февраля 2020

Вы можете получить значения RGB из экземпляра UIColor с помощью встроенного метода:

let color = UIColor(red: 0.3, green: 0.8, blue: 0.4, alpha: 0.9)
var red = CGFloat.zero
var green = CGFloat.zero
var blue = CGFloat.zero
var alpha = CGFloat.zero
color.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
print("r: \(red), g: \(green), b: \(blue)")
...