To achieve a blur view with gradient blur radius, you can do the following (per Apple document):
let ciContext = CIContext(options: nil)
if let inputImage = CIImage(image: yourUIImage) {
let extent = inputImage.extent
let h = extent.size.height
guard let gradient = CIFilter(name: "CILinearGradient") else { return }
gradient.setValue(CIVector(x: 0, y: 0.85 * h), forKey: "inputPoint0")
gradient.setValue(CIColor.green, forKey: "inputColor0")
gradient.setValue(CIVector(x: 0, y: 0.50 * h), forKey: "inputPoint1")
gradient.setValue(CIColor(red: 0, green: 1, blue: 0, alpha: 0), forKey: "inputColor1")
guard let mask = CIFilter(name: "CIMaskedVariableBlur") else { return }
mask.setValue(inputImage.clampedToExtent(), forKey: kCIInputImageKey)
// Set your blur radius here, default is 5
mask.setValue(10, forKey: kCIInputRadiusKey)
mask.setValue(gradient.outputImage, forKey: "inputMask")
guard let output = mask.outputImage,
let cgImage = ciContext.createCGImage(output, from: extent) else { return }
outUIImage = UIImage(cgImage: cgImage)
}
Here, inputPoint0
is the starting point of gradient ramp, inputPoint1
is the ending point. Note that for CIVector
y increases from bottom to top. The input color you set doesn't matter, only its alpha is used to determine blur radius.
For your second question of dynamically applying CIFilter to an image underneath it, no, it's not possible. There is an Apple document on backgroundFilters
that might make you think it is doable, until you see at the bottom ...
This property is not supported on layers in iOS.
What you should do is that, whenever you reset the image, apply the above operation to that image and set it to the image view.