2

I would like to color a white icon to another color in run time, I was trying to use the method taken from here, but without success:

    func maskImageView() {
    var maskImageSize = CGSizeMake(self.downloadImageView.frame.width, self.downloadImageView.frame.height)
    UIGraphicsBeginImageContextWithOptions(maskImageSize, false, 0.0)

    var color = UIColor(white: 1.0, alpha: 1.0)
    color.setFill()

    var rect = CGRectMake(0, 0, self.downloadImageView.frame.width, self.downloadImageView.frame.height)
    UIRectFill(rect)

    color = BrandColors.BRAND_FIRST_COLOR
    color.setFill()

    rect = CGRectMake((self.downloadImageView.frame.width/2)-100, (self.downloadImageView.frame.height/2)-100, 200, 200)
    UIRectFill(rect)

    var maskImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    var maskLayer = CALayer()
    maskLayer.frame = CGRectMake(0, 0, self.downloadImageView.bounds.width, self.downloadImageView.bounds.height)
    maskLayer.contents = maskImage.CGImage
    maskLayer.contentsRect = CGRectMake(0, 0, self.downloadImageView.bounds.width, self.downloadImageView.bounds.height)
    self.downloadImageView.layer.mask = maskLayer;
}

I can't actually figure out how this masking thing works. What am I doing wrong?

halfer
  • 19,824
  • 17
  • 99
  • 186
Emil Adz
  • 40,709
  • 36
  • 140
  • 187

4 Answers4

8

I was able to achieve this task with the following method:

func maskDownloadImageView() {
    downloadImageView.image = downloadImageView.image?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
    downloadImageView.tintColor = BrandColors.BRAND_FIRST_COLOR  
}

There is no need in using masking.

Emil Adz
  • 40,709
  • 36
  • 140
  • 187
  • 1
    Thank you for this! No idea this even existed until now. Saved me a lot of time in photoshop and space in my app bundle. – aasatt Aug 31 '15 at 07:09
0

Try this.

func fillImage(image : UIImage! ,withColor color : UIColor!) -> UIImage!
{
    // Create the proper sized rect
    let imageRect = CGRectMake(0, 0, image.size.width, image.size.height)

    // Create a new bitmap context
    let colorSpace:CGColorSpace = CGColorSpaceCreateDeviceRGB()
    let bitmapInfo = CGBitmapInfo(CGImageAlphaInfo.PremultipliedLast.rawValue)
    let context = CGBitmapContextCreate(nil, Int(imageRect.size.width), Int(imageRect.size.height), 8, 0, colorSpace, bitmapInfo)

    // Use the passed in image as a clipping mask
    CGContextClipToMask(context, imageRect, image.CGImage)
    // Set the fill color
    CGContextSetFillColorWithColor(context, color.CGColor)
    // Fill with color
    CGContextFillRect(context, imageRect)

    // Generate a new image
    let newCGImage = CGBitmapContextCreateImage(context)
    let newImage = UIImage(CGImage: newCGImage)


    return newImage;
}
PowHu
  • 2,159
  • 16
  • 17
0

To mask transparent image try this:

func maskImageWithColor(color : UIColor!) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
    if let context: CGContextRef = UIGraphicsGetCurrentContext() {
        CGContextTranslateCTM(context, 0, self.size.height)
        CGContextScaleCTM(context, 1.0, -1.0)

        CGContextSetBlendMode(context, .Normal)
        let rect: CGRect = CGRectMake(0, 0, self.size.width, self.size.height)

        // To use gradient, add CGColor to Array

        let colors: [CGColor] = [color.CGColor]
        let colorsPointer = UnsafeMutablePointer<UnsafePointer<Void>>(colors)
        if let colorsCFArray = CFArrayCreate(nil, colorsPointer, colors.count, nil) {
            if let space: CGColorSpaceRef = CGColorSpaceCreateDeviceRGB() {
                if let gradient: CGGradientRef = CGGradientCreateWithColors(space, colorsCFArray, nil) {
                    // Apply gradient
                    CGContextClipToMask(context, rect, self.CGImage)
                    CGContextDrawLinearGradient(context, gradient, CGPointMake(0,0), CGPointMake(0, self.size.height), .DrawsBeforeStartLocation)
                    let coloredImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
                    UIGraphicsEndImageContext()

                    return coloredImage;
                }
            }
        }
    }
    return self
}

You can use gradient just adding more CGColor in the array

0

Swift 4 version of Emil Adz answer for the lazy.

func maskDownloadImageView() {
    downloadImageView.image = downloadImageView.image?.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
    downloadImageView.tintColor = BrandColors.BRAND_FIRST_COLOR
}
Tasik
  • 236
  • 6
  • 13