5

Is there any way to create effects like dents, pinching, twisting, squashing, etc. on a UIImage using OpenGL ES as in the iPhone application PhotoTwist?

Are there any references or guidelines for doing this? I don't want code, just a reference on how to do this.

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
Mehul Mistri
  • 15,037
  • 14
  • 70
  • 94
  • see this , by preserving ripple , you will get similar effect as you want actually http://stackoverflow.com/questions/9765709/preserve-ripple-effect-over-uiimageview – HarshIT Mar 27 '12 at 11:57

2 Answers2

16

The most performant way of doing this kind of image processing would be to use OpenGL ES 2.0 shaders. Once again, if I might point you to my GPUImage framework, it can do many of the distortion operations you describe. For those that are missing, you can write your own fragment shaders.

The effects I have in there are a convex bulge distortion (using a GPUImageBulgeDistortionFilter):

Bulge distortion

a concave distortion (using an inverted scale parameter to the previous filter):

Concave distortion

a swirl distortion (using the GPUImageSwirlFilter):

Swirl distortion

and finally, a pinch distortion (using the GPUImagePinchDistortionFilter):

Pinch distortion

If you look at the shaders used for each of the filters, you'll find that the math is very similar between them. You should be able to tweak that to produce your own custom effects from this same base.

It's fairly easy to apply these filters to UIImages. If you have just one filter you'd like to use, you can do something like the following:

UIImage *inputImage = [UIImage imageNamed:@"test.jpg"];
GPUImageBulgeDistortionFilter *stillImageFilter = [[GPUImageBulgeDistortionFilter alloc] init];
UIImage *quickFilteredImage = [stillImageFilter imageByFilteringImage:inputImage];

This will create a UIImage from disk, use OpenGL ES to filter it, and return a filtered UIImage for you to work with. You can use a GPUImagePicture and a custom filter pipeline if you'd like to perform more advanced chained effects, or you can use a different input source for filtering live camera video or movies.

The source code for this project is available at the above link under a BSD license, so you can dig into it to see how to transfer data to and from OpenGL ES and how to perform these kinds of filters.

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
  • GPUImage is a great library! I got the filters working on a static image, but now I am wondering what the best way to smoothly animate a distortion is? – Robert Apr 16 '12 at 19:42
  • 1
    @Robert - You'd want to interpolate between the start point and end point of whatever value is being animated over a set duration. For each new frame, set the property on the filter. For a movie, this will automatically be applied on the next incoming video frame, but you might need to force a re-rendering of your static image using `-processImage`. – Brad Larson Apr 16 '12 at 20:07
  • Great Solution with nice explanation including Example. I like it +10 from myside ;) – Ajay Sharma Sep 14 '12 at 04:42
  • @BradLarson is there any such library for Android? – AAnkit Mar 10 '13 at 12:00
  • Thanks @BradLarson I have gone through this library, it doesnt seems to have distortion filter, The one BulgeDistortion Filter i used for ios App, is not there for Android – AAnkit Mar 10 '13 at 16:53
  • Say @BradLarson ! My entry in "avoid reading the manual at all costs" question of the day .. with the excellent Bulge, is it possible to move the point of the bulge, or is it always the center. thanks! – Fattie Sep 22 '14 at 18:38
  • @JoeBlow - Take a look at the `center` property, which is a normalized 0.0 - 1.0 coordinate for the center of the bulge distortion. You can move that around to change the center of the effect. – Brad Larson Sep 22 '14 at 20:10
  • magnificent, cheers. i'm going to animate it around for a neat effect :) – Fattie Sep 24 '14 at 16:51
  • @BradLarson question about FFTs and You .. ! http://stackoverflow.com/q/26020758/ – Fattie Sep 24 '14 at 17:59
  • The difference between OpenGL (what the poster asked for) and GLSL (GPUImage) can best be illustrated accordingly. Following is the GPUImageBulgeDistortionFilter source: – James Bush Oct 21 '15 at 01:28
  • @JamesBush - Uh, GLSL *is* the OpenGL Shading Language. The above filters were all written in GLSL, so I don't know what you're trying to say. – Brad Larson Oct 21 '15 at 14:26
1

The Photo Editing Extension sample code from the Apple Developer Connection does this exact thing.

James Bush
  • 1,485
  • 14
  • 19
  • I responded to this elsewhere, but to clarify, what you've written above is not [glslang](https://en.wikipedia.org/wiki/OpenGL_Shading_Language), it is the [Core Image kernel language](https://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/CIKernelLangRef/ci_gslang_ext.html#//apple_ref/doc/uid/TP40004397-CH206-BAJJCCHE). The Core Image kernel language, while based on GLSL (glslang), is proprietary and has certain limitations that GLSL does not. For example, the run-time if() statement in the above code will prevent this from compiling and running in Core Image. – Brad Larson Oct 21 '15 at 15:02