Changing the color UIImage

76 Views Asked by At

It is necessary to change the color of the image to 00ff00. But it turns out to 4fff00.

I tried it in two ways. The result is the same.

internal static func imageColorMatrix1(image: UIImage) -> UIImage? {
    let colorMatrix = CIFilter(name: "CIColorMatrix")
    colorMatrix?.setDefaults()
    colorMatrix?.setValue(CIImage(cgImage: image.cgImage!), forKey: kCIInputImageKey)
    colorMatrix?.setValue(CIVector(x: 0.0, y: 0.0, z: 0.0, w: 0.0), forKey: "RVector")
    colorMatrix?.setValue(CIVector(x: 0.0, y: 0.0, z: 0.0, w: 0.0), forKey: "GVector")
    colorMatrix?.setValue(CIVector(x: 0.0, y: 0.0, z: 0.0, w: 0.0), forKey: "BVector")
    colorMatrix?.setValue(CIVector(x: 0.0, y: 0.0, z: 0.0, w: 1.0), forKey: "AVector")
    colorMatrix?.setValue(CIVector(x: 0.0, y: 1.0, z: 0.0, w: 0.0), forKey: "biasVector")
    let outIm = colorMatrix?.outputImage
    let cgIm = CIContext().createCGImage(outIm!, from: outIm!.extent)
    return UIImage(cgImage: cgIm!)
}

or

class ColorFilter: CIFilter {
    var inputImage: CIImage?
    var inputColor: UIColor?
    
    let kernel: CIColorKernel = {
       let kernelString = "kernel vec4 colorize(__sample pixel, vec4 color)\n"
        + "{\n"
        //+ "pixel.rgb = color.rgb;\n"
        + "pixel.r = 0.0;\n"
        + "pixel.g = 1.0;\n"
        + "pixel.b = 0.0;\n"
        + "return pixel;\n"
        + "}\n"
       
        return CIColorKernel(source: kernelString)!
    }()
    
    override var outputImage: CIImage? {
        guard let inputImage = inputImage else {
            return nil
        }
        guard let inputColor = inputColor else {
            return nil
        }
        
        let inputs = [inputImage, CIColor(color: inputColor)] as [Any]
        return kernel.apply(extent: inputImage.extent, arguments: inputs)
    }
}

Calling the class as follows:

internal static func imageColorMatrix1(image: UIImage) -> UIImage? {
    let colorFilter = ColorFilter()
    colorFilter.inputColor = UIColor.green
    colorFilter.inputImage = CIImage(cgImage: image.cgImage!)
    let outIm = colorFilter.outputImage
    let context = CIContext()
    let cgIm = context.createCGImage(outIm!, from: outIm!.extent)
    return UIImage(cgImage: cgIm!)
}

I display it on the UIImageView. Where am I wrong?

2

There are 2 best solutions below

0
Navneet Kaur On
 internal static func imageColorize(image: UIImage, color: UIColor) -> UIImage? {
    let ciImage = CIImage(image: image)
    let filter = CIFilter(name: "CIColorMonochrome")
    filter?.setValue(ciImage, forKey: kCIInputImageKey)
    filter?.setValue(CIColor(color: color), forKey: kCIInputColorKey)
    filter?.setValue(1.0, forKey: kCIInputIntensityKey)
    
    guard let outputImage = filter?.outputImage else { return nil }
    let context = CIContext()
    guard let cgImage = context.createCGImage(outputImage, from: outputImage.extent) else { return nil }
    
    return UIImage(cgImage: cgImage)
}

for passing the hex color create one extension

 extension UIColor {
convenience init(hex: String, alpha: CGFloat = 1.0) {
    var hexSanitized = hex.trimmingCharacters(in: .whitespacesAndNewlines)
    hexSanitized = hexSanitized.replacingOccurrences(of: "#", with: "")

    var rgb: UInt64 = 0

    Scanner(string: hexSanitized).scanHexInt64(&rgb)

    let red = CGFloat((rgb & 0xFF0000) >> 16) / 255.0
    let green = CGFloat((rgb & 0x00FF00) >> 8) / 255.0
    let blue = CGFloat(rgb & 0x0000FF) / 255.0

    self.init(red: red, green: green, blue: blue, alpha: alpha)
 }
}

Use it Like :

let greenImage = BaseViewController.imageColorize(image: UIImage(resource: .coin), color: UIColor(hex: "#00ff00"))

Change BaseViewController with your controller's name

0
Monster On

I got it working properly through the ColorFilter class. There was some problem with converting colors to UIColor. It doesn't work via CIColorMatrix.