'm working on a little app that uses some GPUImage
filters. After playing with it for a while I discovered that if I stack too many of those filters, I run into performance issues.
So now I have two questions:
1.: How to properly stack filters?
The way I am using it currently is to loop over my GPUImageFilters
and let each produce an output and then use that output is the input for the next filter.
I found out that there are FilterGroups
and I tried to use them, but they didn't calculate my output image correctly any more and also produced some crashes that were not reproducible all the times.
So what is the way to go here? I guess my way I'd be wasting a lot of time converting from UIImage
to whatever GPUImage
is using internally? Any ideas on how to improve that?
2.: Is there a way to do it in background?
I read that GPUImage
is not thread save?!? But how would you f.e. filter one image with let's say 100 filters and display them in a UICollectionView
? Any change to do this off thread? Currently I am doing the processing in the main thread and just wait a short amount of time during each image-filtering-process to give the UI some free time...
Any way how to improve that?
Cheers, Georg
If you're going to and from UIImages at each step, you're doing this about the slowest way possible. There's huge overhead in extracting images from a UIImage and converting them back to that, because you're making a roundtrip through Core Graphics and going to and from the CPU.
Instead, if you want to perform multiple operations on a single image, you need to chain your filters using -addTarget:
. Adding a filter as a target of another will cause its output to be fed on the GPU from one stage to the next. This avoids the horribly expensive UIImage-and-back you're doing now.
At the last stage, if you are displaying to the screen, I'd direct your last target to a GPUImageView. Otherwise, you can extract your UIImage from that final stage.
GPUImage cannot currently be used in an iOS background process, due to its need for OpenGL ES access. However, that restriction lightened up in iOS 8, so it may be possible to do this now. Haven't taken the time to check on this.
If you want to filter one image using many filters, you can take one image input and target it to multiple filters simultaneously. Upon processing that image, all filters will act as they can. The GPU is the limiting part of that process, and I already use a multithreaded internal dispatch queue, so you don't need to worry about running that one multiple threads.