• Stars
    star
    932
  • Rank 49,020 (Top 1.0 %)
  • Language
    Swift
  • License
    GNU General Publi...
  • Created over 9 years ago
  • Updated over 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Apply a Gaussian Blur to any UIView with Swift Protocol Extensions

Blurable

###Apply a Gaussian Blur to any UIView with Swift Protocol Extensions

Adds blur() and unBlur() methods to UIView components which applies a Core Image Gaussian blur filter to the contents.

######Companion project to this blog post: http://flexmonkey.blogspot.co.uk/2015/09/applying-gaussian-blur-to-uiviews-with.html

screengrab

Here's a fun little experiment showing the power of Swift's Protocol Extensions to apply a CIGaussianBlur Core Image filter to any UIView with no developer overhead. Blurable components can be simple labels or buttons or more complex composite components such as UISegmentedControls and they can reside as subviews of other UIViews including UIStackViews. The code could be extended to apply any Core Image filter such as a half tone screen or colour adjustment.

Blurable is a simple protocol that borrows some of the methods and variables from a UIView:

    var layer: CALayer { get }
    var subviews: [UIView] { get }
    var frame: CGRect { get }
    var superview: UIView? { get }
    
    func addSubview(view: UIView)

    func bringSubviewToFront(view: UIView)

...and adds a few of its own:

    func blur(blurRadius blurRadius: CGFloat)
    func unBlur()
    
    var isBlurred: Bool { get }

Obviously, just being a protocol, it doesn't do much on its own. However, by adding an extension, I can introduce default functionality. Furthermore, by extending UIView to implement Blurable, every component from a label to a segmented control to a horizontal slider can be blurred:

    extension UIView: Blurable
    {

    }

Installation

Manually

  1. Download and drop FMBlurable.swift in your project.
  2. Congratulations!

##The Mechanics of Blurable

Getting a blurred representation of a UIView is pretty simple: I need to begin an image context, use the view's layer's renderInContext method to render into the context and then get a UIImage from the context:

    UIGraphicsBeginImageContextWithOptions(CGSize(width: frame.width, height: frame.height), false, 1)
    
    layer.renderInContext(UIGraphicsGetCurrentContext()!)
    
    let image = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext();

Once I have the image populated, it's a fairly standard workflow to apply a Gaussian blur to it:

    guard let blur = CIFilter(name: "CIGaussianBlur") else
    {
        return
    }

    blur.setValue(CIImage(image: image), forKey: kCIInputImageKey)
    blur.setValue(blurRadius, forKey: kCIInputRadiusKey)
    
    let ciContext  = CIContext(options: nil)
    
    let result = blur.valueForKey(kCIOutputImageKey) as! CIImage!
    
    let boundingRect = CGRect(x: 0,
        y: 0,
        width: frame.width,
        height: frame.height)
    
    let cgImage = ciContext.createCGImage(result, fromRect: boundingRect)

    let filteredImage = UIImage(CGImage: cgImage)

A blurred image will be larger than its input image, so I need to be explicit about the size I require in createCGImage.

The next step is to swap out the blurred component from its superview for a UIImageView containing the blurred image. The technique for doing this differs depending on whether the superview is a UIStackView and the blurred component is an arranged subview or not. I've already created a constant named this that is a non-optional, strongly typed reference to self as a UIView, so I can go ahead and check its superview and, if it's a UIStackView insert the blurred view as an arranged subview:

    if let superview = superview as? UIStackView,
        index = (superview as UIStackView).arrangedSubviews.indexOf(this)
    {
        removeFromSuperview()
        superview.insertArrangedSubview(blurOverlay, atIndex: index)
    }

However, if the blurred component isn't an arranged subview, we can use a nice animation to cross fade between the original and the blurred view:

    else
    {
        blurOverlay.frame.origin = frame.origin

        UIView.transitionFromView(this,
            toView: blurOverlay,
            duration: 0.2,
            options: UIViewAnimationOptions.CurveEaseIn,
            completion: nil)
    }

Finally, we need to create a reference between the original blurred component and its blur overlay. Since protocol extensions don't allow for stored properties, I use objc_setAssociatedObject to effectively add a blurOverlay property to the component:

    objc_setAssociatedObject(this,
        &BlurableKey.blurable,
        blurOverlay,
        objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)

When it comes to unblurring in unBlur(), it's essentally the same process but in reverse. First I create the same this constant and ensure the component has an associated blur overlay:

    guard let this = self as? UIView,
        blurOverlay = objc_getAssociatedObject(self as? UIView, &BlurableKey.blurable) as? BlurOverlay else
    {
        return
    }

Then do the same checks to see if blurOverlay's superview is a UIStackView and either insert self as an arranged subview if it is or do the same transitionFromView animation as above, but backwards, if it isn't:

    if let superview = blurOverlay.superview as? UIStackView,
        index = (blurOverlay.superview as! UIStackView).arrangedSubviews.indexOf(blurOverlay)
    {
        blurOverlay.removeFromSuperview()
        superview.insertArrangedSubview(this, atIndex: index)
    }
    else
    {
        this.frame.origin = blurOverlay.frame.origin

        UIView.transitionFromView(blurOverlay,
            toView: this,
            duration: 0.2,
            options: UIViewAnimationOptions.CurveEaseIn,
            completion: nil)
    }

The last step of unBlur() is to remove the association between the original blurred component and its blur overlay:

    objc_setAssociatedObject(this,
        &BlurableKey.blurable,
        nil,
        objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)

Finally, to see if a UIView is currently blurred, I created isBlurred() which just needs to check if it has an associated blur overlay:

    var isBlurred: Bool
    {
        return objc_getAssociatedObject(self as? UIView, &BlurableKey.blurable) is BlurOverlay
    }

##Blurring a UIView

To blur and de-blur, just invoke blur() and unBlur() on an UIView:

    segmentedControl.unBlur()
    segmentedControl.blur(blurRadius: 2)

##Source Code

As always, the source code for this project is available at my GitHub repository here. Enjoy!

More Repositories

1

Filterpedia

Core Image Filter Explorer & Showcase
Swift
2,241
star
2

Plum-O-Meter

3D Touch Application for Weighing Plums (and other small fruit!)
Swift
528
star
3

ParticleLab

Particle system that's both calculated and rendered on the GPU using the Metal framework
Swift
493
star
4

sweetcorn

Node based CIKernel creation
Swift
261
star
5

SmoothScribble

Smooth Drawing for iOS in Swift with Hermite Spline Interpolation
Swift
241
star
6

MarkingMenu

Swift MarkingMenu
Swift
217
star
7

CartoonEyes

Composite Cartoon Eyes over Face from Front Camera with CoreImage
Swift
163
star
8

LiveCameraFiltering

Demonstration of applying a Comic Book filter to a live video feed
Swift
151
star
9

SwiftSpace

CoreMotion Controlled Drawing in 3D Space
Swift
150
star
10

ShinpuruLayout

Simple Layout in Swift using HGroups & VGroups
Swift
128
star
11

ForceSketch

Demonstration of a Sketching App Using 3D Touch
Swift
109
star
12

ParticleCam

Metal based particle system influenced by iPad camera
Swift
102
star
13

ShinpuruImage

Syntactic Sugar for Accelerate/vImage and Core Image Filters
Swift
100
star
14

ShinpuruNodeUI

Node Based UI Component Written in Swift
Swift
98
star
15

ValentinesSwift

You love Swift & Swift loves you!
Swift
89
star
16

CoreImageForSwiftPlaygrounds

CoreImage For Swift Playgrounds
Swift
88
star
17

SnapSwift

SnapSeed Style Popup Menu for iOS
Swift
87
star
18

CoreImageHelpers

Syntactic sugar for displaying CIImage using OpenGL and grabbing CIImages from iOS cameras
Swift
73
star
19

VideoEffects

iPad app to open videos from file system, apply Core Image filters and save result back SavedPhotosAlbum
Swift
71
star
20

AudioKitNodality

AudioKitNodality
Swift
69
star
21

MetalReactionDiffusion

Reaction Diffusion using Swift & Metal
Swift
69
star
22

3D-Motion-Controller

Using MultipeerConnectivity and CoreMotion to allow an iPhone to act as a 3D mouse for an iPad app
Swift
67
star
23

Globular

Colourful SpriteKit Metaballs Controlled by 3D Touch
Swift
67
star
24

Interpolation-Playground-

Swift playground demonstrating lerp, smooth step, Catcall-Rom and others!
Swift
63
star
25

Nebula

Core Image Volumetric Rendering
Swift
60
star
26

MetalKit-Particles

An implementation of my Metal ParticleLab component for OS X 10.11 and iOS 9
Swift
57
star
27

AdvancedTouch

Swift Advanced Touch Handling in iOS9: Coalescing and Prediction
Swift
50
star
28

MetalVideoCapture

Demo of Creating a Metal Texture from AVCaptureSession and Applying MetalPerformanceShaders In-Place
Swift
50
star
29

AudioSynthesis

CoreAudio for Sound Synthesis Demonstration
Swift
48
star
30

UIScrollViewDemo

A Node Based User Interface implemented with the Presentation Model Pattern
Swift
41
star
31

SwiftCFD

CPU Based Navier Stokes Computational Fluid Dynamics in Swift for iOS
Swift
41
star
32

StrangeAttractor

Lorenz Attractor in Swift & Metal
Swift
39
star
33

Spritely

Using SpriteKit events to trigger AudioKit sounds
Swift
39
star
34

SwiftGoo

Kai's Power Tools Goo - written in Swift!
Swift
38
star
35

Scribe

Handwriting and Stroke Recognition in Swift
Swift
37
star
36

DeepPressGestureRecognizer

UIGestureRecognizer for recognising deep press 3D Touch on iPhone 6s
Swift
35
star
37

MercurialPaint

Mercurial Painting using Metal and Core Image
Swift
33
star
38

PencilController

Using Apple Pencil as a 3D Controller for Image Editing
Swift
30
star
39

CoreImagePerspectivePlayground

Core Image Perspective Playground
Swift
28
star
40

GameplayKitAgents

A Look at Agents, Goals & Behaviours in GameplayKit
Swift
27
star
41

CoreImageFluidDynamics

CIFilter / CIKernel based fluid dynamics
Swift
26
star
42

SceneKitMaterialEditor

A very simple app for editing SceneKit materials
Swift
26
star
43

DepthOfFieldExplorer

SceneKit Depth of Field Demonstration
Swift
26
star
44

ChromaTouch

Introduction to 3D Touch in Swift with Peek, Pop and Preview Actions
Swift
26
star
45

3D-ReTouch

Experimental Retouching App using 3D Touch
Swift
26
star
46

FurrySketch

Using Apple Pencil's Azimuth & Altitude Data for Creating Directional Furry Brush Strokes
Swift
26
star
47

Purikura

Bulging eyes Purikura effect
Swift
25
star
48

SkyCubeTextureDemo

A demonstration of using MDLSkyCubeTexture in a SceneKit project
Swift
25
star
49

CoreImageConvolutionExplorer

CoreImageConvolutionExplorer
Swift
24
star
50

CIImage-UIImage-Orientation-Fix

Demo of UIImageOrientation to TIFF Orientation conversion that fixes orientation issues when creating CIImage from UIImage
Swift
24
star
51

ImageToneCurveEditor

Project demonstrating the use of CIToneCurve
Swift
24
star
52

PencilSynth

An Audiokit Synthesiser Controller by Apple Pencil
Swift
23
star
53

CoreImageTransitionExplorer

Simple slide show demonstration using Core Image Transitions and PHImageManager
Swift
22
star
54

SceneKitProceduralNormalMapping

Demo of Core Image filter to create SceneKit normal maps from procedural bump maps
Swift
22
star
55

ForceZoom

Zoom Into Image Details using 3D Touch Peek
Swift
21
star
56

PendulaTone

Audio driven by pendulum waves
Swift
20
star
57

Rotatable

Swift Protocol Extension to Rotate any UIView
Swift
19
star
58

PhotoBrowserDemo

A Swift image browser/picker for use with PHImageManager
Swift
19
star
59

Protocol-Extension-Event-Dispatcher

Implementation of EventDispatcher pattern using Swift Protocol Extensions
Swift
18
star
60

ImageProcessingWithMetal

An introduction to image processing with Metal and Swift
17
star
61

WheelTone

Audio synthesis driven by a network of friction gears
Swift
15
star
62

FilterChainingDemo

Demonstration of chaining a series of CIFilters together
Swift
15
star
63

ConvolutionExplorer

vImage / Accelerate convolution filter in Swift
Swift
14
star
64

Bokeh

Demonstration of simulation of hexagonal bokeh using Metal Performance Shaders
Swift
14
star
65

SpriteKitMotionBlur

SpriteKitMotionBlur
Swift
14
star
66

FMNixieDisplay

Nixie Tube Display Component on Swift
Swift
14
star
67

MercurialText

Embossed Type using SceneKit and CIShadedMaterial
Swift
14
star
68

GPUImageDemo

GPUImageDemo
Swift
12
star
69

Christmas-Tree-Bowling

Apple Pencil Controlled Christmas Tree Bowling!
Swift
12
star
70

GestureRecognizer

Demo of custom UIGestureRecognizer
Swift
11
star
71

NumericDialDemo

NumericDialDemo
Swift
11
star
72

ProgSConCompanion

ProgSConCompanion
Swift
10
star
73

CoreImageReactionDiffusion

Gary-Scott reaction Diffusion Implemented as a Core Image CIKernel
Swift
10
star
74

MetalKit-ReactionDiffusion

Reaction diffusion simulation using Metal Kit with parameter gradients controlled by the camera
Swift
10
star
75

PencilScale

Using an Apple Pencil with an iPad Pro as an electronic scale
Swift
9
star
76

GrayScott

Non GPU GrayScott Reaction Diffusion Experiment Using NSOperation
Swift
9
star
77

FMHierarchicalSelector

Hierarchical Selector Component based on UIPickerView & UICollectionView
Swift
9
star
78

NemoCam

Virtual underwater video recording using Filterpedia's Caustic Refraction Filter
Swift
9
star
79

InnerPlanetCurves

Draws Cubic Bezier Curve Between Earth & Venus Using Mercury & Mars as Control Points
Swift
8
star
80

BristlePaint

Embossed Painting with Individual Bristles using SpriteKit Normal Mapping
Swift
8
star
81

StackView

A first play with Swift 2's UIStackView
Swift
8
star
82

MPS_Equalisation

Demonstration of Histogram Equalisation with Metal Performance Shaders
Swift
7
star
83

CoreImageReductionFilterExplorer

App demonstrating extracting color data from CIAreaAverage and displaying Core Image Histograms
Swift
7
star
84

Vertigo

Vertigo inducing colourful painting...
Swift
6
star
85

CoreImageCathodeRayTube

Simple cathode ray tube simulation CIKernel processing live feed from iOS camera.
Swift
5
star
86

Swift3_CoreImageDemo

Swift3_CoreImageDemo
Swift
4
star
87

LondonSwiftDemo

Demo Project for London Swift
Swift
4
star
88

Swarm-Chemistry-GCD

New Version of Swarm Chemistry, using GCD and Bitmap creation
Swift
4
star
89

PHImageManagerTwitterDemo

Demonstration of PHImageManager and Twitter Integration
Swift
3
star
90

CoreImageVoronoi

Full screen animated Moroni noise!
Swift
3
star
91

PhysicsExperiments

Swift
3
star
92

InlineMethodTest

Testing performance of inline code versus instance methods versus class methods
Swift
3
star
93

StPatricksDay

Happy St Patricks Day!
Swift
3
star
94

HisogramSpecificationBlendDemo

Demonstration of Histogram Specification for Image Composition
Swift
2
star
95

SelectorPlayground

Demonstration of `#selector` expression
Swift
2
star
96

FlexMonkeyExamples

Files to support posts in http://flexmonkey.blogspot.co.uk/
Swift
2
star
97

SwiftExperiments

Swift experiments
Swift
1
star
98

Swarm-Chemistry

DEPRECATED: Multithreaded CPU based Swarm Chemistry
Swift
1
star
99

ArraySpeedTest

Some simple tests looking at the performance of different techniques populating and interrogating arrays
Swift
1
star
100

GaussianPlayground

Demonstration of creating a Gaussian blur using separate vertical and horizontal convolution filters.
Swift
1
star