3

iOS 8 introduces some pretty snazzy interactive blurring. Most notably, there's the interactive blur when you pull down for spotlight, but there's also the animation when opening and closing Siri (though that's not interactive). I've only noticed this interactive blur in one other place: the official Twitter app when pulling down on a profile view (parallax header image zooms and blurs sometimes).

I've attempted to animate something basic with a UISlider with both CoreImage and GPUImage (based on the answer to this question and also Apple's UIImage+ImageEffects, but nothing seems appropriately performant enough to animate the blur interactively (i.e. blurring an image to a single value works quickly once, but not at a framerate fast enough to blur continuously).

How can I implement these methods in a way that they are performant enough to both blur and unblur a UIImage (and ideally a UIView or CIContext snapshot) interactively?

Community
  • 1
  • 1
brandonscript
  • 68,675
  • 32
  • 163
  • 220
  • Take a screenshot of your view, then blur the screenshot. http://stackoverflow.com/questions/18942037/blur-screen-with-ios-7s-snapshot-api – Nick Wilkerson Nov 16 '14 at 06:56
  • @NickWilkerson keyword here is **interactively**. Both the posts I linked to are doing exactly that, but they aren't performant enough unless running in GCD dispatch_async, and then it's not thread safe. – brandonscript Nov 16 '14 at 06:58
  • 1
    How about precalculating the frames (with different levels of blur if I understand your question correctly) before starting your animation, so that you have them available in memory during the animation? – quentinadam Nov 16 '14 at 07:38
  • @goldmine interesting idea... animate with what, CAKeyFrameAnimations? – brandonscript Nov 16 '14 at 07:38
  • Yes. I worked on something like this previously to produce a glowing button (lightening up in a sinusoidal fashion and repeating). I used CAKeyFrameAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"] and provided an array of timestamps with [animation setKeyTimes:times] and an array of UIImages with [animation setValues:values]. – quentinadam Nov 16 '14 at 07:44
  • As discussed here: http://stackoverflow.com/questions/18804668/gpuimage-animated-gaussian-blur-filter , you can kinda cheat on this by blurring the background, then animating a crossfade between the blurred image and the original sharp one. That gives you interactive performance without having to manage varying blur radii at each step. – Brad Larson Nov 17 '14 at 02:32
  • @BradLarson yeah, tried that too and it's just not as "BAM!" beautiful – brandonscript Nov 17 '14 at 02:48
  • 1
    found this on reddit, might be what you're looking for http://www.reddit.com/r/iOSProgramming/comments/2jjuec/how_does_apple_achieve_the_slidedown_blur_effect/ – akaralar May 08 '15 at 01:03
  • @akaralar wow that's crazy - it actually looks like it works. I'll have to give it a shot. – brandonscript May 08 '15 at 02:58

1 Answers1

0

There is no simple and one way of doing it, but it's definitively doable if you follow following steps and optional ways:

  1. Most important: downsample the image. Basic resolution is not very important for gaussian blur. If you downsample only to half resolution, the amount of data is down to quarter!

  2. Define end target blur radius.

  3. Retrieve the architecture of device with the help of C functions and use different values of delta saturation parameter for different architectures, according to processing power, of course.

  4. Experiment creating the blur with Apple provided library with radius step regarding to step value of parameter that is interacting with (KVO to contentOffset property, for example). dispatch_async and don't forget to callback with blurred image to main queue!

  5. Methods above will almost for sure cater all the architectures from arm7s onwards, but you might still have some issues with arm7 - iPhone 4s).

  6. If you still have issues, like with mentioned arm7, then double the contentOffset change required to make next blur with next radius. Then instead of changing the image property on UIImageView, rather create new UIImageView with new blurred UIImage and fade in alpha channel from 0 to 1 within the period the next blurred page is being created.

  7. You might use number of tricks, like creating all blurred images one after another for the full interactive scale and cache them in collection and use them in method described in point 6.

There a also many other techniques if the animation is not interactive, but rather timed in the certain frame.

mbpro
  • 2,460
  • 3
  • 22
  • 37