Потребовалось много времени, чтобы выяснить это, в основном потому, что я хотел запустить его в Swift, используя Core Image и CIColorCube.
@ Мигель объясняет, как вам нужно заменить«Диапазон угла оттенка» с другим «Диапазон угла оттенка».Вы можете прочитать его пост выше для подробностей о том, что такое Угловой диапазон оттенка.
Я сделал быстрое приложение, которое заменяет синий грузовик по умолчанию ниже на то, что вы выберете на ползунке оттенка.

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


Обратите внимание, что он не окрашивает шины или задние фонари, потому что этоза пределами 60-градусного диапазона стандартного синего оттенка грузовика, но он правильно обрабатывает затенение.
Сначала вам нужен код для преобразования RGB в HSV (значение оттенка):
func RGBtoHSV(r : Float, g : Float, b : Float) -> (h : Float, s : Float, v : Float) {
var h : CGFloat = 0
var s : CGFloat = 0
var v : CGFloat = 0
let col = UIColor(red: CGFloat(r), green: CGFloat(g), blue: CGFloat(b), alpha: 1.0)
col.getHue(&h, saturation: &s, brightness: &v, alpha: nil)
return (Float(h), Float(s), Float(v))
}
Затемвам нужно конвертировать HSV в RGB.Вы хотите использовать это, когда обнаружите оттенок, который находится в желаемом диапазоне оттенков (он же, цвет того же синего оттенка, что и у грузовика по умолчанию), чтобы отменить любые сделанные вами настройки.
func HSVtoRGB(h : Float, s : Float, v : Float) -> (r : Float, g : Float, b : Float) {
var r : Float = 0
var g : Float = 0
var b : Float = 0
let C = s * v
let HS = h * 6.0
let X = C * (1.0 - fabsf(fmodf(HS, 2.0) - 1.0))
if (HS >= 0 && HS < 1) {
r = C
g = X
b = 0
} else if (HS >= 1 && HS < 2) {
r = X
g = C
b = 0
} else if (HS >= 2 && HS < 3) {
r = 0
g = C
b = X
} else if (HS >= 3 && HS < 4) {
r = 0
g = X
b = C
} else if (HS >= 4 && HS < 5) {
r = X
g = 0
b = C
} else if (HS >= 5 && HS < 6) {
r = C
g = 0
b = X
}
let m = v - C
r += m
g += m
b += m
return (r, g, b)
}
Теперь выпросто переберите полный цветовой куб RGBA и «отрегулируйте» любые цвета в диапазоне оттенков «по умолчанию синий» с теми из вашего нового желаемого оттенка.Затем используйте Core Image и фильтр CIColorCube, чтобы применить отрегулированный цветовой куб к изображению.
func render() {
let centerHueAngle: Float = 214.0/360.0 //default color of truck body blue
let destCenterHueAngle: Float = slider.value
let minHueAngle: Float = (214.0 - 60.0/2.0) / 360 //60 degree range = +30 -30
let maxHueAngle: Float = (214.0 + 60.0/2.0) / 360
var hueAdjustment = centerHueAngle - destCenterHueAngle
let size = 64
var cubeData = [Float](count: size * size * size * 4, repeatedValue: 0)
var rgb: [Float] = [0, 0, 0]
var hsv: (h : Float, s : Float, v : Float)
var newRGB: (r : Float, g : Float, b : Float)
var offset = 0
for var z = 0; z < size; z++ {
rgb[2] = Float(z) / Float(size) // blue value
for var y = 0; y < size; y++ {
rgb[1] = Float(y) / Float(size) // green value
for var x = 0; x < size; x++ {
rgb[0] = Float(x) / Float(size) // red value
hsv = RGBtoHSV(rgb[0], g: rgb[1], b: rgb[2])
if hsv.h < minHueAngle || hsv.h > maxHueAngle {
newRGB.r = rgb[0]
newRGB.g = rgb[1]
newRGB.b = rgb[2]
} else {
hsv.h = destCenterHueAngle == 1 ? 0 : hsv.h - hueAdjustment //force red if slider angle is 360
newRGB = HSVtoRGB(hsv.h, s:hsv.s, v:hsv.v)
}
cubeData[offset] = newRGB.r
cubeData[offset+1] = newRGB.g
cubeData[offset+2] = newRGB.b
cubeData[offset+3] = 1.0
offset += 4
}
}
}
let data = NSData(bytes: cubeData, length: cubeData.count * sizeof(Float))
let colorCube = CIFilter(name: "CIColorCube")!
colorCube.setValue(size, forKey: "inputCubeDimension")
colorCube.setValue(data, forKey: "inputCubeData")
colorCube.setValue(ciImage, forKey: kCIInputImageKey)
if let outImage = colorCube.outputImage {
let context = CIContext(options: nil)
let outputImageRef = context.createCGImage(outImage, fromRect: outImage.extent)
imageView.image = UIImage(CGImage: outputImageRef)
}
}
Образец проекта можно загрузить здесь .