Adding Gaussian Blur to Swift Mobile App’s UIView
Adding Gaussian blur to the UIView of your mobile application can improve its user experience a lot. Let me show you three simple ways to apply this popular visual effect in Swift.
Table of Content- Case Study: Highlighting Custom Alerts with Gaussian Blur
- Adding Gaussian Blur with CIFilters
- Implementing Gaussian Blur with the UIBlurEffect
- The Ultimate Approach: Gaussian smoothing with kernels
- Wrapping up
TL;DR
- You can use Gaussian blur (or Gaussian smoothing as some called it) for different reasons in your mobile app, for example when it shows custom alerts to its users.
- You can either use `CIGaussianBlur` from the `CIFilter` group of functional filters to get the Gaussian smoothing added easily.
- Or you may as well use `UIBlurEffect` for your project, though it has limitations when it comes to blurring transparency and it can be a bit difficult to apply to every component of the views.
- You can add Gaussian blur to your app and save precious scaling time with simple techniques like convolutions and high-speed kernels. Read on for details.
Case Study: Highlighting Custom Alerts with Gaussian Blur
- Case Study: Highlighting Custom Alerts with Gaussian Blur
- Adding Gaussian Blur with CIFilters
- Implementing Gaussian Blur with the UIBlurEffect
- The Ultimate Approach: Gaussian smoothing with kernels
- Wrapping up
TL;DR
- You can use Gaussian blur (or Gaussian smoothing as some called it) for different reasons in your mobile app, for example when it shows custom alerts to its users.
- You can either use `CIGaussianBlur` from the `CIFilter` group of functional filters to get the Gaussian smoothing added easily.
- Or you may as well use `UIBlurEffect` for your project, though it has limitations when it comes to blurring transparency and it can be a bit difficult to apply to every component of the views.
- You can add Gaussian blur to your app and save precious scaling time with simple techniques like convolutions and high-speed kernels. Read on for details.
Case Study: Highlighting Custom Alerts with Gaussian Blur
In my app, I needed to show custom alerts with some data and options for users. The idea was to blur the background of the app, to make the alert more visible. The users had to make their minds immediately and take action, so there was not much time for editing the view. Both the custom alert and blurred background needed to be displayed at once.
As I didn’t want to mess up my Storyboard, I decided to pass the data from one UIViewController to another. Let’s call them:
`DecisionViewController -> AlertViewController`
.
The action would take place in `AlertViewController`. Then, when the action is taken, the controller would be closed and the `DecisionViewController` would be refreshed. Piece of cake, you think? Well, it depends. Let’s check the code!
If I want to show the view from `DecisionViewController` in `AlertViewController`, I need to take a screenshot of the first one and pass it to another controller. This is the function I use:
swift
func takeScreenshot() -> UIImage {
if let layer = UIApplication.shared.keyWindow?.layer {
UIGraphicsBeginImageContext(layer.frame.size)
if let context = UIGraphicsGetCurrentContext() {
layer.render(in: context)
}
}
return UIGraphicsGetImageFromCurrentImageContext() ?? UIImage()
}
This is quite easy and fast, isn’t it?
In `AlertViewController`, I created `UIImageView` that receives the background and shows it as the background for alerts.
But how do I blur the image?
I needed a visual effect from Apple’s class CIFilter. It looks pretty easy to implement.
1. Adding Gaussian Blur with CIFilters
Apple provides many functional filters grouped under the name `CIFilter`. Among them you can find `CIGaussianBlur` which is great for adding the desiredsmoothing to your image. As a part of `UIKit` framework, it’s also easy to implement.
So this is my code for adding Gaussian blur to the image:
func addBlurTo(_ image: UIImage) -> UIImage? {
guard let ciImg = CIImage(image: image) else { return nil }
let blur = CIFilter(name: "CIGaussianBlur")
blur?.setValue(ciImg, forKey: kCIInputImageKey)
blur?.setValue(5.0, forKey: kCIInputRadiusKey)
if let outputImg = blur?.outputImage {
return UIImage(ciImage: outputImg)
}
return nil
}
Now, all you need is to display the blurred image. Piece of cake.
But this `func` can be even more simple.
Applying `CIFilters` in Swift can be achieved faster if you change `UIImage` to `CIImage` and apply the `applyingFilter()` method. Adding parameters like `kCIInputRadiusKey` is also possible. Just use `applyingFilter(_ filterName: String, parameters params: [String : Any])`. Let’s check it out.
func addBlurTo(_ image: UIImage) -> UIImage? {
if let ciImg = CIImage(image: image) {
ciImg.applyingFilter("CIGaussianBlur")
return UIImage(ciImage: ciImg)
}
return nil
}
2. Implementing Gaussian Blur with the UIBlurEffect
This is, I think, the most standard way - using `UIBlurEffect` from the `UIVisualEffect` class. `UIBlurEffect` is a very easy, fast and stable solution, but it also has limitations.
First, you must remember that `UIBlurEffect` isn't an image filter. It's just a `UIView` effect that can be applied on image (and actually on any view).
This is how it looks:
let view = UIView()
let blurEffect = UIBlurEffect(style: .light)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
view.addSubview(blurEffectView)
As you can see, UIBlurEffect can be added to any view without taking a screenshot.
Let's get back to the limitations.
- With `UIBlurEffect`, you can't modify the transparency of the blurring. You can modify alpha, but that’s it. If, for example, you want to blur your view just a little, UIBlurEffect will just becloud the entire view and after applying tit, you won't be able to see what is in the background. No "opacity" option.
- You won’t be able to blur everything in your app with UIBlurEffect. If you want to use UIBlurEffect, you have to know that this effect is settled in hierarchy of Views. It means, it's under UINavigationController, UITabBarController, let alone Status Bar. So, sorry, you won’t be able to blur every part of your app without changing the position of the controllers mentioned before. And this is something that may cause problems.
Both approaches I’ve used so far are the most convenient ways to implement Gaussian blur in Swift.
They, however, have one big limitation: time.
Depending on how big your input image is, scaling it to add the blur in your mobile app can take up to a few seconds. This is far too long. Most users won’t wait 2-3 seconds for the options view. It has to be displayed immediately.
This made me look for yet another solution.
3. The Ultimate Approach: Gaussian smoothing with kernels
This is how I found Apple’s great article about blurring images. The sample code presented in the article shows not only how Gaussian blur works in Swift, but also how to implement it in your project.
This method calls low-level techniques such as convolution - for example vImageConvolve_ARGB8888.
What’s the advantage of it? Long story short, using convolution and high-speed kernels saves time. A lot.
Convolution operations are based on kernels. There can be user 1D and 2D grids. Grids indicate neighboring pixels and calculate their value, so there is no need to waste time on scaling an image.
For my app, I use a simple 1D kernel, but for more complex blurring I can always use some more sophisticated solutions.
The final function works with the vImageBuffer_Init method that uses vImage_Buffer(), vImageConvolve_ARGB8888, and changes the image format to vImage_CGImageFormat.
If you’re not familiar with these methods, just download the code from Apple’s article - this should show you how it works in details. I made a few changes here and there, but the code provided by Apple is ready to use.
Using high-speed kernels requires to import Accelerate, so don’t forget about this in your project. You should also remember that functions like vImageConvolve_ARGB8888 require to alloc and free memory - something that isn’t every day routine for Swift. This is why we use lazy var for vImage_CGImageFormat and others. Also, you should check twice the memory allocation, as this may cause many further problems with crashing the app among them.
Wrap Up
Gaussian blur (or Gaussian smoothing) effect can be a nice addition when you need to show custom alerts to your application’s users. If you are programming in Swift, there are at least three ways of applying it.
You can blur the image either by applying the CIGaussianBlur functional filter or choose the most usual approach, the UIBlurEffect from the UiVisualEffect class. Both of them are easily accessible via UIKit.
Both of them, though, have significant limitations that can work to your project’s disadvantage. These are: lack of control over the transparency level in UIBlurEffect, inability to blur any part of an app you like with it, and, last but not least, the relatively slow scaling time.
In contrast to these options, using convolution and kernels seems to be the most effective approach. It reduces the scaling time, so the Gaussian blur is shown in the blink of an eye.