Reputation: 59
I have been gradually getting my head around filters but I can't for the life of me get this to work and there are minimal articles about this specific filter.
I have a mask (png) with a gradient between white and black and an image and I can't get it to blur an image called bg.png. The app crashes out with:
'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key inputMaskImage.'
let mask = CIImage(image: UIImage(named: "mask.png")!)
let context = CIContext()
let filter = CIFilter(name: "CIMaskedVariableBlur")
filter?.setValue(mask, forKey: kCIInputMaskImageKey)
let image = CIImage(image: UIImage(named: "bg.png")!)
filter?.setValue(image, forKey: kCIInputImageKey)
let result = filter?.outputImage!
let cgImage = context.createCGImage(result!, from:(result?.extent)!)
let outputImg = UIImage(cgImage: cgImage!)
bgImage.image = outputImg
I have been playing around with different ways of doing it but all give the same error and I assume it is to do with the mask type?... I have no idea!
Upvotes: 0
Views: 1504
Reputation: 559
This code crops the image to the extent of the original image:
func applyMaskedVariableBlur(image: UIImage, mask: UIImage) -> UIImage {
let filter = CIFilter(name: "CIMaskedVariableBlur")
// convert UIImages to CIImages and set as input
let ciInput = CIImage(image: image)
let ciMask = CIImage(image: mask)
filter?.setValue(ciInput?.clampedToExtent(), forKey: "inputImage")
filter?.setValue(ciMask, forKey: "inputMask")
filter?.setValue(20, forKey: "inputRadius")
// get output CIImage, render as CGImage first to retain proper UIImage scale
let ciOutput = filter?.outputImage
let ciContext = CIContext()
let croppedCi = ciOutput?.cropped(to: ciInput!.extent)
let cgImage = ciContext.createCGImage(croppedCi!, from: (croppedCi?.extent)!)
let processedImage = UIImage(cgImage: cgImage!, scale: image.scale, orientation: image.imageOrientation)
return processedImage
}
Upvotes: 0
Reputation:
If you are targeting iOS 8, the key kCIInputMaskImageKey
won't work. It's only for iOS 9 or later. But the good news is you can get things to work in iOS 8 by typing in the name of the keys. I usually do this anyways. Here's a function that should work for you:
func applyMaskedVariableBlur(image:UIImage, mask:UIImage) -> UIImage {
let filter = CIFilter(name: "CIMaskedVariableBlur")
// convert UIImages to CIImages and set as input
let ciInput = CIImage(image: image)
let ciMask = CIImage(image: mask)
filter?.setValue(ciInput, forKey: "inputImage")
filter?.setValue(ciMask, forKey: "inputMask")
// get output CIImage, render as CGImage first to retain proper UIImage scale
let ciOutput = filter?.outputImage
let ciContext = CIContext()
let cgImage = ciContext.createCGImage(ciOutput!, from: (ciOutput?.extent)!)
return UIImage(cgImage: cgImage!)
}
Upvotes: 3