royherma
royherma

Reputation: 4203

How to correctly alternate between different filters of UIImage (GPUImage)

I am working on a filtering application, similar to the GPUImage "filterShowCase" project, but am focusing on filtering static images (selected from the user's library). The main view displays the image selected by the imagepicker as follows:

sourcePicture = [[GPUImagePicture alloc] initWithImage:sourceImage smoothlyScaleOutput:YES];
filter = [[GPUImageSepiaFilter alloc] init];

filterView = [[GPUImageView alloc]initWithFrame:self.view.frame];
    filterView.contentMode = UIViewContentModeScaleAspectFit;
    filterView.clipsToBounds = YES;

//Setup targets
[sourcePicture addTarget:filter];
[filter addTarget:filterView];
[sourcePicture processImage];

[self.view addSubview:filterView];

This all works, and the image is filtered in sepia. I am allowing a user to change filters based on user input, in aim for quick alternation between different filters - this is all done in a switch statement...

switch (filterNumber)
    {
case GPUIMAGE_SEPIA:
        {
            self.title = @"Sepia Tone";


            filter = [[GPUImageSepiaFilter alloc] init];
        }; break;
//a bunch of other filters...

}
    [sourcePicture removeAllTargets];
    [sourcePicture addTarget:filter];
    [filter addTarget:filterView];
    [sourcePicture processImage];

This (^) is the current process I am using, but there is a small time interval between the filter type selection and the actual modification of the image to match that filter.

I previously tried just doing [sourcePicture processImage] but that didn't work (didn't change the image in the GPUImageView), so what am i doing something wrong? - or is the intended performance of the system?

Thanks!

ANSWER Look at Brad Larsons' comment to this question.

Upvotes: 0

Views: 984

Answers (3)

royherma
royherma

Reputation: 4203

As Brad Larson wrote, using the [filter forceProcessingAtSize] will reduce the execution time of the filters.

Upvotes: 1

Dipak Narigara
Dipak Narigara

Reputation: 1806

Use this method for switch filtering , just pass your filter name string in Method

-(void)filterImage:(NSString *)aStrFilterOption {


    CIImage *_inputImage = [CIImage imageWithCGImage:[imgOriginal CGImage]];
    CIFilter *filter = [CIFilter filterWithName:aStrFilterOption];
    [filter setValue:_inputImage forKey:kCIInputImageKey];

    CGImageRef moi3 = [[CIContext contextWithOptions:nil]
                       createCGImage:filter.outputImage
                       fromRect:_inputImage.extent];
    imgView.image = [UIImage imageWithCGImage:moi3];
    CFRelease(moi3);
}

Upvotes: 0

ophychius
ophychius

Reputation: 2653

I have an app that sort of does the same, and what I do is that I keep my baseImage at hand, and once I am done applying the filter and showing the image with filter I reset everything. The moment a user selects a different filter I use the baseImage again to create the new filtered image and show it.

So in this example you could for example move the [sourcePicture removeAllTargets]; to right after this [self.view addSubview:filterView];

That saves you work when you want to apply a new filter. Also, there is a quicker (dirtier way to filter a picture when you are working with an image that already exists. I got this from the documentation that came with GPUImage and it works like a charm.

GPUImageSketchFilter *stillImageFilter2 = [[GPUImageSketchFilter alloc] init];
tmp = [stillImageFilter2 imageByFilteringImage:[self baseImage]];
[self.imageView setImage: tmp];
tmp = nil;

Hope it helps you on your way.

Upvotes: 0

Related Questions