BradLarson / GPUImage

An open source iOS framework for GPU-based image and video processing
http://www.sunsetlakesoftware.com/2012/02/12/introducing-gpuimage-framework
BSD 3-Clause "New" or "Revised" License
20.25k stars 4.61k forks source link

Lookup Filter in chain of filters #654

Open dansinclair25 opened 12 years ago

dansinclair25 commented 12 years ago

Hi,

I'm trying to add a custom Lookup Filter to a chain of other adjustable filters but when I add the custom Lookup Filter, the adjustable filters don't work.

Here's what I have to setup the filters;

self.lookup = [[GPUImageLookupTestFilter alloc] initWithLookup:[UIImage imageNamed:@"lookup.png"]];

self.brightness = [[GPUImageBrightnessFilter alloc] init];
[self.brightness setBrightness:self.bFloat];

self.contrast = [[GPUImageContrastFilter alloc] init];
[self.contrast setContrast:self.cFloat];

self.saturation = [[GPUImageSaturationFilter alloc] init];
[self.saturation setSaturation:self.sFloat];

self.sepia = [[GPUImageSepiaFilter alloc] init];
[self.sepia setIntensity:self.sepFloat];

self.vignette = [[GPUImageVignetteFilter alloc] init];
[self.vignette setVignetteEnd:self.vFloat];

[self.pic addTarget:self.brightness];

[self.brightness addTarget:self.contrast];
[self.contrast addTarget:self.saturation];
[self.saturation addTarget:self.sepia];
[self.sepia addTarget:self.vignette];
[self.vignette addTarget:self.lookup];

[self.lookup addTarget:self.imageView];

[self.pic processImage];

and here's my custom Lookup Filter Class;

GPUImageLookupTestFilter.h

#import "GPUImageFilterGroup.h"

@class GPUImagePicture;

@interface GPUImageLookupTestFilter : GPUImageFilterGroup
{
GPUImagePicture *lookupImageSource;
}

@property (nonatomic, retain) GPUImagePicture *lookupImageSource;

-(id)initWithLookup:(UIImage *)image;

@end

GPUImageLookupTest.m

#import "GPUImageLookupTestFilter.h"
#import "GPUImagePicture.h"
#import "GPUImageLookupFilter.h"

@implementation GPUImageLookupTestFilter
@synthesize lookupImageSource;

-(id)init;
{
if (!(self = [super init]))
{
    return nil;
}

return self;
}

-(id) initWithLookup: (UIImage *)img;
{
if (!(self = [super init]))
{
    return nil;
}

UIImage *image = img;
NSAssert(image, @"To use GPUImageLookupTestFilter you need to add lookup_test.png from GPUImage/framework/Resources to your application bundle.");

lookupImageSource = [[GPUImagePicture alloc] initWithImage:image];
GPUImageLookupFilter *lookupFilter = [[GPUImageLookupFilter alloc] init];

[lookupImageSource addTarget:lookupFilter atTextureLocation:1];
[lookupImageSource processImage];

self.initialFilters = [NSArray arrayWithObjects:lookupFilter, nil];
self.terminalFilter = lookupFilter;

return self;

}

#pragma mark -
#pragma mark Accessors

@end

all of which works perfectly by itself if I call

[[GPUImageLookupTestFilter alloc] initWithLookup:[UIImage imageNamed:@"lookup.png"]]

but when I add it to the chain of filters, I cannot update them using a UISlider (as per the FilterShowcase example)

Any ideas?

Thanks in advance.

Dan

phil-m commented 12 years ago

Hey Dan,

I haven't seen that issue with lookups in a chain using video, & haven't tried a chain of filters with a lookup on still images, but did come across an issue when adding an intensity/strength option to a lookup filter when using it on a still image.

Whenever the intensity value was changed, the lookup wouldn't update unless '[lookupImageSource processImage];' was called. I'm not sure if that is the proper/correct fix, but it seems to be working ok, & may be worth checking out for your issue. Although I'm not sure where that should be called in your case, but maybe as a quick test you could add a method that simply runs processImage, & call that manually whenever you change your slider, just to see if it possibly helps fix it.

Phil

iamcam commented 11 years ago

I don't have any success by calling processImage, but it seems in my app I can verify that the lookup filter isn't forwarding the image output into the next filter in the chain.

Still Image (photo) -> Crop -> Group -> Blend w/ Image -> View

Everything works well when changing the group filter as long as it doesn't contain a lookup. I've spent about a full day trying to figure out what was going on here only to realize I think the problem is with the lookup filter, not my code, as every other plugin I have seems to work normally. None of those use lookup filters.

iamcam commented 11 years ago

After a couple days of trying to problem solve this issue ... and two different versions of filter setup refactoring ... I came back here and thought I'd give this a shot. I use filter switching in my app and couldn't, for the life of me, get the lookup filters (namely MissEtikate and Amatorka) to update downstream filters

@phil-m you hit the nail on the head. I copied the source from the MissEtikate filter into my own, but added

-(void)prepareForImageCapture {
    [lookupImageSource processImage];
    [super prepareForImageCapture];
}

And it looks like I'm in the clear. It appears any filter that makes use of GPUImageLookupFilter will need to extend prepareForImageCapture as demonstrated above or you'll possibly run into problems.

I'll submit a pull request with the changes to GPUImageMissEtikateFilter, GPUImageAmatorkaFilter, and GPUImageSoftEleganceFilter

iamcam commented 11 years ago

(not that it matters, but ignore the first commit reference - the pull request I attempted to make with had a bunch of changes that I didn't intend to send back through a pull request. I deleted my repo and re-cloned it for a clean pull request)