I want to blur the whole screen of my iOS app, and I can't use UIBlurEffect
because I want to be able to control the blurriness. So I'm trying to use CIGaussianBlur
, but I'm having trouble with the edges of the screen.
I'm taking a screenshot of the screen, and then running it through a CIFilter
with CIGaussianBlur
, converting the CIImage
back to UIImage
, and adding the new blurred image on top of the screen.
Here's my code:
let layer = UIApplication.sharedApplication().keyWindow?.layer
UIGraphicsBeginImageContext(view.frame.size)
layer!.renderInContext(UIGraphicsGetCurrentContext()!)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let blurRadius = 5
var ciimage: CIImage = CIImage(image: screenshot)!
var filter: CIFilter = CIFilter(name:"CIGaussianBlur")!
filter.setDefaults()
filter.setValue(ciimage, forKey: kCIInputImageKey)
filter.setValue(blurRadius, forKey: kCIInputRadiusKey)
let ciContext = CIContext(options: nil)
let result = filter.valueForKey(kCIOutputImageKey) as! CIImage!
let cgImage = ciContext.createCGImage(result, fromRect: view.frame)
let finalImage = UIImage(CGImage: cgImage)
let blurImageView = UIImageView(frame: view.frame)
blurImageView.image = finalImage
blurImageView.sizeToFit()
blurImageView.contentMode = .ScaleAspectFit
blurImageView.center = view.center
view.addSubview(blurImageView)
Here is what I see:
It looks almost right except the edges. It seems that the blurrisness is taking off from the blur radius to the edge. I tried playing with the context size but couldn't seem to make it work.
How can I make the blur go all the way to the edges?
It is happening because the gaussian blur filter samples pixels outside the edges of the image. But because there are no pixels, you get this weird artefact. You can use "CIAffineClamp"
filter to "extend" your image infinitely in all directions.
Please see this answer https://stackoverflow.com/a/18138742/762779
I tried running your code with chained 'CIAffineClamp-> CIGaussianBlur' filters and got good results.
let layer = UIApplication.sharedApplication().keyWindow?.layer
UIGraphicsBeginImageContext(view.frame.size)
layer!.renderInContext(UIGraphicsGetCurrentContext()!)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let blurRadius = 5
let ciimage: CIImage = CIImage(image: screenshot)!
// Added "CIAffineClamp" filter
let affineClampFilter = CIFilter(name: "CIAffineClamp")!
affineClampFilter.setDefaults()
affineClampFilter.setValue(ciimage, forKey: kCIInputImageKey)
let resultClamp = affineClampFilter.valueForKey(kCIOutputImageKey)
// resultClamp is used as input for "CIGaussianBlur" filter
let filter: CIFilter = CIFilter(name:"CIGaussianBlur")!
filter.setDefaults()
filter.setValue(resultClamp, forKey: kCIInputImageKey)
filter.setValue(blurRadius, forKey: kCIInputRadiusKey)
let ciContext = CIContext(options: nil)
let result = filter.valueForKey(kCIOutputImageKey) as! CIImage!
let cgImage = ciContext.createCGImage(result, fromRect: ciimage.extent) // changed to ciiimage.extend
let finalImage = UIImage(CGImage: cgImage)
let blurImageView = UIImageView(frame: view.frame)
blurImageView.image = finalImage
blurImageView.sizeToFit()
blurImageView.contentMode = .ScaleAspectFit
blurImageView.center = view.center
view.addSubview(blurImageView)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With