Shubhendu
Shubhendu

Reputation: 1091

GPUImage crashing in iOS 8

I have implemented a filter tool mechanism which has many filters. Each filter contains 2-3 different filters i.e. i am using GPUImageFilterGroup for this. Now when i updated GPU Image Library for iOS 8 compatible it shows "Instance Method prepareForImageCapture not found" and app crashes.

enter image description here

I also tried to implement the following code

GPUImageFilterGroup *filter = [[GPUImageFilterGroup alloc] init];

    GPUImageRGBFilter *stillImageFilter1 = [[GPUImageRGBFilter alloc] init];
//    [stillImageFilter1 prepareForImageCapture];

    stillImageFilter1.red = 0.2;
    stillImageFilter1.green = 0.8;
        [stillImageFilter1 useNextFrameForImageCapture];
    [(GPUImageFilterGroup *)filter addFilter:stillImageFilter1];

    GPUImageVignetteFilter *stillImageFilter2 = [[GPUImageVignetteFilter alloc] init];
//    [stillImageFilter1 prepareForImageCapture];
    stillImageFilter2.vignetteStart = 0.32;
    [stillImageFilter1 useNextFrameForImageCapture];
    [(GPUImageFilterGroup *)filter addFilter:stillImageFilter2];

    [stillImageFilter1 addTarget:stillImageFilter2];

    [(GPUImageFilterGroup *)filter setInitialFilters:[NSArray arrayWithObject:stillImageFilter1]];
    [(GPUImageFilterGroup *)filter setTerminalFilter:stillImageFilter2];

    GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:image];
    [stillImageSource addTarget:(GPUImageFilterGroup *)filter];
    [stillImageSource processImage];

    UIImage *img = [(GPUImageFilterGroup *)filter imageFromCurrentFramebuffer];

Its returning nil image. Can anyone tell me whats the correct way!!!

Thanks in advance.

Upvotes: 1

Views: 1020

Answers (1)

Brad Larson
Brad Larson

Reputation: 170309

First, that wasn't a crash for iOS 8. You haven't updated your copy of GPUImage in a while, and that method was removed months ago in an update unrelated to any iOS compatibility. The reasons for this are explained here and I'll once again quote the relevant paragraph:

This does add one slight wrinkle to the interface, though, and I've changed some method names to make this clear to anyone updating their code. Because framebuffers are now transient, if you want to capture an image from one of them, you have to tag it before processing. You do this by using the -useNextFrameForImageCapture method on the filter to indicate that the next time an image is passed down the filter chain, you're going to want to hold on to that framebuffer for a little longer to grab an image out of it. -imageByFilteringImage: automatically does this for you now, and I've added another convenience method in -processImageUpToFilter:withCompletionHandler: to do this in an asynchronous manner.

As you can see, -prepareForImageCapture was removed because it was useless in the new caching system.

The reason why your updated code is returning nil is that you've called -useNextFrameForImageCapture on the wrong filter. It needs to be called on your terminal filter in the group (stillImageFilter2) and only needs to be called once, right before you call -processImage. That signifies that this particular framebuffer needs to hang around long enough to have an image captured from it.

You honestly don't need a GPUImageFilterGroup in the above, as it only complicates your filter chaining.

Upvotes: 3

Related Questions