How can you apply distortions to a UIImage using OpenGL ES?

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.

Leave a Comment