Search code examples
iosimage-processingswift4rgba

swift4 how to change color of black and white image using filter


I want to change color of black and white image which is page of a book. I have done this using for loop which change color pixel by pixel and it is taking too much time.

var p2b: RGBAPixel = RGBAPixel(r: 0, g: 153, b: 0)
var p2t: RGBAPixel = RGBAPixel(r: 255, g: 255, b: 255)
for y in 0 ..< height {
    for x in 0 ..< width {

         let p1 = img.getPixel(x, y: y)

        if ( p1.red > 200 ) { img2.setPixel(p2b, x: x, y: y) }

        else { img.setPixel(p2t, x: x, y: y) }
    }
}

is there faster way to do this?


Solution

  • this is only for black and white image e.g image of a book page

    get image as CIImage and make two pixels just like this newPix1 and newPix2

    var ciimage: CIImage
    ciimage = CIImage(image: myImg)!     
    
    var newPix1 = EFUIntPixel()
    newPix1.red = UInt8(25); newPix1.green = UInt8(25); newPix1.blue = 
    UInt8(25); newPix1.alpha = UInt8(200)
    
    var newPix2 = EFUIntPixel()
    newPix2.red = UInt8(0); newPix2.green = UInt8(255); newPix2.blue = 
    UInt8(255); newPix2.alpha = UInt8(200)
    

    now call function to replace color

    ciimage = ciimage.replace(colorNew: newPix1, colorNew2: newPix2, 
    isFirst: true)!
    

    white color of image will be replaced by newPix1 and black color will be newPix2

    don't forget to add following code, you can put it where you want

    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
        func replace(colorNew: EFUIntPixel,colorNew2: EFUIntPixel, isFirst: Bool) -> CIImage? {
            let cubeSize = 64
            let cubeData = { () -> [Float] in
                let selectColor = (Float(0.862745106), Float(0.862745106), Float(0.862745106), Float(0.784313738))
                let raplaceColor = (Float(colorNew.red) / 255.0, Float(colorNew.green) / 255.0, Float(colorNew.blue) / 255.0, Float(colorNew.alpha) / 255.0)
    
                let raplaceColor2 = (Float(colorNew2.red) / 255.0, Float(colorNew2.green) / 255.0, Float(colorNew2.blue) / 255.0, Float(colorNew2.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 = (raplaceColor2.0, raplaceColor2.1, raplaceColor2.2, raplaceColor2.3)
                            }
                            // Select colorOld
                            else 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
        }
    }