Skip to content

Instantly share code, notes, and snippets.

@EyreFree
Last active April 27, 2020 04:47
Show Gist options
  • Save EyreFree/ab91a7f5b962147d0984e8ea114be766 to your computer and use it in GitHub Desktop.
Save EyreFree/ab91a7f5b962147d0984e8ea114be766 to your computer and use it in GitHub Desktop.
iOS CIImage Replace color with another one in Swift 3.1
import Foundation
struct EFUIntPixel {
var red: UInt8 = 0
var green: UInt8 = 0
var blue: UInt8 = 0
var alpha: UInt8 = 0
}
extension CIImage {
// Replace color with another one
// https://github.com/dstarsboy/TMReplaceColorHue/blob/master/TMReplaceColorHue/ViewController.swift
func replace(colorOld: EFUIntPixel, colorNew: EFUIntPixel) -> CIImage? {
let cubeSize = 64
let cubeData = { () -> [Float] in
let selectColor = (Float(colorOld.red) / 255.0, Float(colorOld.green) / 255.0, Float(colorOld.blue) / 255.0, Float(colorOld.alpha) / 255.0)
let raplaceColor = (Float(colorNew.red) / 255.0, Float(colorNew.green) / 255.0, Float(colorNew.blue) / 255.0, Float(colorNew.alpha) / 255.0)
var data = [Float](repeating: 0, count: cubeSize * cubeSize * cubeSize * 4)
var tempRGB: [Float] = [0, 0, 0]
var newRGB: (r : Float, g : Float, b : Float, a: Float)
var offset = 0
for z in 0 ..< cubeSize {
tempRGB[2] = Float(z) / Float(cubeSize) // blue value
for y in 0 ..< cubeSize {
tempRGB[1] = Float(y) / Float(cubeSize) // green value
for x in 0 ..< cubeSize {
tempRGB[0] = Float(x) / Float(cubeSize) // red value
// Select colorOld
if tempRGB[0] == selectColor.0 && tempRGB[1] == selectColor.1 && tempRGB[2] == selectColor.2 {
newRGB = (raplaceColor.0, raplaceColor.1, raplaceColor.2, raplaceColor.3)
} else {
newRGB = (tempRGB[0], tempRGB[1], tempRGB[2], 1)
}
data[offset] = newRGB.r
data[offset + 1] = newRGB.g
data[offset + 2] = newRGB.b
data[offset + 3] = 1.0
offset += 4
}
}
}
return data
}()
let data = cubeData.withUnsafeBufferPointer { Data(buffer: $0) } as NSData
let colorCube = CIFilter(name: "CIColorCube")!
colorCube.setValue(cubeSize, forKey: "inputCubeDimension")
colorCube.setValue(data, forKey: "inputCubeData")
colorCube.setValue(self, forKey: kCIInputImageKey)
return colorCube.outputImage
}
}
@Eloreden
Copy link

Eloreden commented Apr 3, 2018

Something wrong... if color is betweek 0 and 255 color and temprgb is betweem 0 - 63 if i have a grey color like (175,175,175) never found inside image...

so where i wrong to use this part of code?

this is what i do:

let color1 : EFUIntPixel = EFUIntPixel(red: 175, green: 175, blue: 175, alpha: 1)
let replaceImage : CIImage = CIImage(cgImage: image.cgImage!);
DispatchQueue.main.async {
       let imageReplace : UIImage = UIImage(ciImage: replaceImage.replace(colorOld: color1, colorNew: EFUIntPixel(red: 1, green: 0, blue: 0, alpha: 0))!)
       self.colorMOd.image = imageReplace
        }

this happen because never can be true this if

tempRGB[0] == selectColor.0 && tempRGB[1] == selectColor.1 && tempRGB[2] == selectColor.2

so for found the color we need to insert a range near the "1/64" -> so i have apply this change:

var rCondition = false
                        var gCondition = false
                        var bCondition = false
                        if tempRGB[0] < selectColor.0 + 0.005 && tempRGB[0] > selectColor.0 - 0.005 {
                            rCondition = true
                        }
                        if tempRGB[1] < selectColor.1 + 0.005 && tempRGB[1] > selectColor.1 - 0.005 {
                            gCondition = true
                        }
                        if tempRGB[2] < selectColor.2 + 0.005 && tempRGB[2] > selectColor.2 - 0.005 {
                            bCondition = true
                        }
                        
                        if rCondition && gCondition && bCondition{
                            print("Color Found")
                            newRGB = (1,1,1,1) //(raplaceColor.0, raplaceColor.1, raplaceColor.2, raplaceColor.3)
                        }else{
                            newRGB = (tempRGB[0], tempRGB[1], tempRGB[2], 1)
                        }

now the true problem is: nothing change in the image... Why?

@edit: ok i have a white background and if i swap white with red run... why?

@caka1011
Copy link

Something wrong... if color is betweek 0 and 255 color and temprgb is betweem 0 - 63 if i have a grey color like (175,175,175) never found inside image...

so where i wrong to use this part of code?

this is what i do:

let color1 : EFUIntPixel = EFUIntPixel(red: 175, green: 175, blue: 175, alpha: 1)
let replaceImage : CIImage = CIImage(cgImage: image.cgImage!);
DispatchQueue.main.async {
       let imageReplace : UIImage = UIImage(ciImage: replaceImage.replace(colorOld: color1, colorNew: EFUIntPixel(red: 1, green: 0, blue: 0, alpha: 0))!)
       self.colorMOd.image = imageReplace
        }

this happen because never can be true this if

tempRGB[0] == selectColor.0 && tempRGB[1] == selectColor.1 && tempRGB[2] == selectColor.2

so for found the color we need to insert a range near the "1/64" -> so i have apply this change:

var rCondition = false
                        var gCondition = false
                        var bCondition = false
                        if tempRGB[0] < selectColor.0 + 0.005 && tempRGB[0] > selectColor.0 - 0.005 {
                            rCondition = true
                        }
                        if tempRGB[1] < selectColor.1 + 0.005 && tempRGB[1] > selectColor.1 - 0.005 {
                            gCondition = true
                        }
                        if tempRGB[2] < selectColor.2 + 0.005 && tempRGB[2] > selectColor.2 - 0.005 {
                            bCondition = true
                        }
                        
                        if rCondition && gCondition && bCondition{
                            print("Color Found")
                            newRGB = (1,1,1,1) //(raplaceColor.0, raplaceColor.1, raplaceColor.2, raplaceColor.3)
                        }else{
                            newRGB = (tempRGB[0], tempRGB[1], tempRGB[2], 1)
                        }

now the true problem is: nothing change in the image... Why?

@edit: ok i have a white background and if i swap white with red run... why?

Hi there. Could you find a working solution for doing the replacement properly?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment