I would like to perform a “smart” blur to a UIImage, where the contents are blurred, but the edges remain sharp.
For example, here is my original image:

and here is what I would like to see after this blur is applied:

How can I do a “smart” blur like this on a UIImage?
The blur you’re looking for here is called a bilateral blur. Unlike a standard Gaussian blur, surrounding pixel colors are averaged with the center pixel color based on how similar they are to the central pixel. This blurs interior regions of objects, but preserves a sharp outline.
In my open source GPUImage framework, I have a filter that does this, called a GPUImageBilateralFilter. This is the output of that when applied to your image (using a blurSize of 1.0 and a distanceNormalizationFactor of 1.6):
There are some slight differences between my result and your target, but that’s probably due to the specific weightings I use. By tweaking the parameters here, you should be able to get this closer to the above.
OpenCV also has bilateral blur filters, and you could take the source code to my fragment shader and use this to construct your own OpenGL ES implementation if you’d like to use it outside of this framework: