Reputation: 11
I have searched everywhere and found a few examples on how to mask an image, but none of them seem to work for me... I am running on iOS9 and using Swift2.0
Right now this is what I have:
class func maskImage(background: UIImage, withMask mask: UIImage) -> UIImage {
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedLast.rawValue).rawValue
let colorSpace = CGColorSpaceCreateDeviceRGB()!
let context = CGBitmapContextCreate(nil, CGImageGetWidth(mask.CGImage), CGImageGetHeight(mask.CGImage), 8, 0, colorSpace, bitmapInfo)
CGContextDrawImage(context, CGRectMake(0, 0, mask.size.width * mask.scale, mask.size.height * mask.scale), mask.CGImage)
let maskRef: CGImageRef = CGBitmapContextCreateImage(context)!
let masked: CGImageRef = CGImageCreateWithMask(background.CGImage, maskRef)!
let icon: UIImage = UIImage(CGImage: masked, scale: mask.scale, orientation: mask.imageOrientation)
return icon
}
I am passing two pngs in and getting the error: EXC_BAD_INSTRUCTION on the line where I initialize masked. I don't have enough rep to post the image.
I am probably missing something super simple, but would love your help. Thank you!
Upvotes: 1
Views: 2270
Reputation: 79
With Swift 3.0 we have had the great name change.... so this appears to function now after some renaming... and cleaning... based on this example: ( https://www.innofied.com/implementing-image-masking-in-ios/ )
func maskImage(image:UIImage, mask:UIImage )->UIImage{
let imageReference = (image.cgImage)!
let maskReference = (mask.cgImage)!
let imageMask = CGImage.init(
maskWidth: maskReference.width
,height: maskReference.height
,bitsPerComponent: maskReference.bitsPerComponent
,bitsPerPixel: maskReference.bitsPerPixel
,bytesPerRow: maskReference.bytesPerRow
,provider: maskReference.dataProvider!
,decode: nil
,shouldInterpolate: true
)
return (UIImage(cgImage:(imageReference.masking(imageMask!))!))
}
Upvotes: 1
Reputation: 180
In case anybody stumbles across this same situation and is looking for a clean solution, here's a function to mask an image. It works for .jpg, .png and .gif images.
func maskImage(image:UIImage, mask:(UIImage))->UIImage{
let imageReference = image.CGImage
let maskReference = mask.CGImage
let imageMask = CGImageMaskCreate(CGImageGetWidth(maskReference),
CGImageGetHeight(maskReference),
CGImageGetBitsPerComponent(maskReference),
CGImageGetBitsPerPixel(maskReference),
CGImageGetBytesPerRow(maskReference),
CGImageGetDataProvider(maskReference), nil, true)
let maskedReference = CGImageCreateWithMask(imageReference, imageMask)
let maskedImage = UIImage(CGImage:maskedReference!)
return maskedImage
}
Add the following declaration lines in your viewDidLoad() or init() as needed :
let image = UIImage(named: "image.png")
let maskingImage = UIImage(named: "mask.png")
let imageView = UIImageView(image: maskingImage)
imageView.image = maskImage(image!, mask: maskingImage!)
Thanks to Manish Kumar's solution Implementing Image Masking in iOS
Upvotes: 0
Reputation: 1053
I am also running the latest versions and had a lot of trouble with this. I was finally able to use the below code to crop part of an image and overlay a puzzle piece with an image mask.
import UIKit
import CoreGraphics
class ViewController2: UIViewController {
@IBOutlet var imageView: UIImageView!
var p1PosX: CGFloat = 0.0
var p1PosY: CGFloat = 0.0
var p1Width: CGFloat = 0.0
var p1Height: CGFloat = 0.0
override func viewDidLoad() {
super.viewDidLoad()
let panda = UIImage(named: "panda.jpeg")!
let puzzle1 = UIImage(named: "PP-4-1.gif")!
//Crop
let contextSize: CGSize = panda.size
let rect = CGRect(x: 0, y: 0, width: 200, height: 200)
p1PosX = 0
p1PosY = 0
p1Width = contextSize.width / 2
p1Height = contextSize.height / 2
let rect1: CGRect = CGRectMake(p1PosX, p1PosY, 350, 350)
let imageRef1: CGImageRef = CGImageCreateWithImageInRect(panda.CGImage, rect1)!
let panda1: UIImage = UIImage(CGImage: imageRef1, scale: panda.scale, orientation: panda.imageOrientation)
imageView.image = panda1
//Mask
UIGraphicsBeginImageContext(imageView.frame.size)
panda1.drawInRect(rect)
puzzle1.drawInRect(CGRectMake(0, 0, imageView.frame.size.width , imageView.frame.size.height), blendMode: CGBlendMode.DestinationIn, alpha: 1.0)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
imageView.image = newImage
}
}
Upvotes: 0