Pavan K
Pavan K

Reputation: 4693

changing the tint of the image in swift

I am new to swift and trying to achieve this essentially, This image to enter image description here

This image ->

enter image description here

I am using this code from here to change the tint on image but do not get the desired output

func tint(image: UIImage, color: UIColor) -> UIImage
{
    let ciImage = CIImage(image: image)
    let filter = CIFilter(name: "CIMultiplyCompositing")

    let colorFilter = CIFilter(name: "CIConstantColorGenerator")
    let ciColor = CIColor(color: color)
    colorFilter.setValue(ciColor, forKey: kCIInputColorKey)
    let colorImage = colorFilter.outputImage

    filter.setValue(colorImage, forKey: kCIInputImageKey)
    filter.setValue(ciImage, forKey: kCIInputBackgroundImageKey)

    return UIImage(CIImage: filter.outputImage)!
}

If this is a noob question, apologies. I was able to do this easily in javascript but not in swift.

Upvotes: 3

Views: 4152

Answers (3)

Duncan C
Duncan C

Reputation: 131491

Your image is simple and only has one color. I would suggest making your image transparent except where the lines are, and then layer it on top of a white background to get your results.

It looks like you got the results you're after using drawing modes. There are also a number of Core image filters that let you apply tinting effects to images, as well as replacing specific colors. Those would be a good choice for more complex images.

Upvotes: 0

sarosh mirza
sarosh mirza

Reputation: 702

hi you can use it the following way. First the UIImage Extension that you used needs some updates. you can copy the code below for Swift 3

extension UIImage{
func tint(color: UIColor, blendMode: CGBlendMode) -> UIImage
{

    let drawRect = CGRect(x: 0,y: 0,width: size.width,height: size.height)
    UIGraphicsBeginImageContextWithOptions(size, false, scale)
    color.setFill()
    UIRectFill(drawRect)
    draw(in: drawRect, blendMode: blendMode, alpha: 1.0)
    let tintedImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return tintedImage!
}
}

Then in your viewDidLoad where you are using the image for example i used the image from IBOutlet imageWood

    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    self.imageWood.image = self.imageWood.image?.tint(color: UIColor.green, blendMode: .saturation)
}

You will have to use the appropriate color and the images

The other Extension i found

extension UIImage {

// colorize image with given tint color
// this is similar to Photoshop's "Color" layer blend mode
// this is perfect for non-greyscale source images, and images that have both highlights and shadows that should be preserved
// white will stay white and black will stay black as the lightness of the image is preserved
func tint(_ tintColor: UIColor) -> UIImage {

    return modifiedImage { context, rect in
        // draw black background - workaround to preserve color of partially transparent pixels
        context.setBlendMode(.normal)
        UIColor.black.setFill()
        context.fill(rect)

        // draw original image
        context.setBlendMode(.normal)
        context.draw(self.cgImage!, in: rect)

        // tint image (loosing alpha) - the luminosity of the original image is preserved
        context.setBlendMode(.color)
        tintColor.setFill()
        context.fill(rect)

        // mask by alpha values of original image
        context.setBlendMode(.destinationIn)
        context.draw(self.cgImage!, in: rect)
    }
}

// fills the alpha channel of the source image with the given color
// any color information except to the alpha channel will be ignored
func fillAlpha(_ fillColor: UIColor) -> UIImage {

    return modifiedImage { context, rect in
        // draw tint color
        context.setBlendMode(.normal)
        fillColor.setFill()
        context.fill(rect)

        // mask by alpha values of original image
        context.setBlendMode(.destinationIn)
        context.draw(self.cgImage!, in: rect)
    }
}


fileprivate func modifiedImage(_ draw: (CGContext, CGRect) -> ()) -> UIImage {

    // using scale correctly preserves retina images
    UIGraphicsBeginImageContextWithOptions(size, false, scale)
    let context: CGContext! = UIGraphicsGetCurrentContext()
    assert(context != nil)

    // correctly rotate image
    context.translateBy(x: 0, y: size.height);
    context.scaleBy(x: 1.0, y: -1.0);

    let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)

    draw(context, rect)

    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image!
}

}

Using it like this

self.imageWood.image = self.imageWood.image?.tint(UIColor.purple.withAlphaComponent(1))

Upvotes: 2

Santosh
Santosh

Reputation: 2914

Try the below code, should work for you.

    if let myImage = UIImage(named: "imageName")?.withRenderingMode(.alwaysTemplate) {
        myImageView.image = myImage
        myImageView.tintColor = UIColor.white
    }

Upvotes: 0

Related Questions