GPUImage animated Gaussian blur filter

I used the GPUImage Gaussian blur filter to blur the still image. I want to associate the size of the blur to a UI element, and when the element is resized by the user, I blur the image. The way I am doing it now is to change the blurSize when a significant (> 0.25) change has occurred, reapply the filter and animate the new image in the imageView.

Is there a more efficient way for me to do this?

On the iPhone 5, while performance isn't laggy, it's not too smooth (but maybe that's because the operation is simply too expensive to be super smooth).

+2


source to share


1 answer


interest Ask. Your best bet is to pre-compute and map the CGImages to a couple of blurry weights in your range, and then use two stacked UIImageViews, with one on top showing a rougher copy but partially transparent. For example, if you blurred in radii 1,2,3, ..., 10 and you wanted to show 3.7, you would show image 3 at the bottom and image 4 at the top, with 70% opacity.



// Created in answer to Nikhil Varma question at http://stackoverflow.com/questions/18804668/gpuimage-animated-gaussian-blur-filter
#import "GPUImage.h"
#define BLUR_STEP 2.
@interface AHViewController : UIViewController

@property (weak, nonatomic) IBOutlet UIImageView *imageView2;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (nonatomic) CGFloat blurRadius;
@property (nonatomic, strong) UIImage *image;
@property (nonatomic, strong) GPUImageGaussianBlurFilter *blurFilter;
@property (nonatomic, strong) NSCache *blurredImageCache;
@property (nonatomic, strong) dispatch_queue_t blurQueue;
@property (nonatomic, strong) NSMutableSet *blurAmountsBeingRendered;
@end

@implementation AHViewController

-(void)viewDidLoad {
    [super viewDidLoad];
    self.image = [UIImage imageNamed:@"ph.jpg"];
    self.blurFilter = [GPUImageGaussianBlurFilter new];
    self.blurredImageCache = [NSCache new];
    self.blurQueue = dispatch_queue_create("Image Blur Queue", DISPATCH_QUEUE_SERIAL);
    self.blurAmountsBeingRendered = [NSMutableSet set];
    self.blurRadius = 1.0;
}
- (IBAction)sliderDidMove:(UISlider *)sender {
    self.blurRadius = 10 * sender.value;
}
-(void)setBlurRadius:(CGFloat)blurRadius {
    _blurRadius = blurRadius;
    CGFloat smaller = self.blurRadius - fmodf(self.blurRadius, BLUR_STEP);
    [self asyncGenerateImageWithBlurAmount:smaller];
    CGFloat larger = smaller + BLUR_STEP;
    [self asyncGenerateImageWithBlurAmount:larger];

}
-(UIImage *)cachedImageWithBlurAmount:(CGFloat)blur {
    return [self.blurredImageCache objectForKey:@(blur)];
}
-(void)asyncGenerateImageWithBlurAmount:(CGFloat)blur {
    // This image is already available.
    if([self.blurredImageCache objectForKey:@(blur)]) {
        [self imageIsAvailableWithBlur:blur];
        return;
    }
    // There already a render going on for this. Just return.
    if([self.blurAmountsBeingRendered containsObject:@(blur)])
        return;

    // Start a render
    [self.blurAmountsBeingRendered addObject:@(blur)];
    dispatch_async(self.blurQueue, ^{
        self.blurFilter.blurSize = blur;
        UIImage *result = [self.blurFilter imageByFilteringImage:self.image];
        [self.blurredImageCache setObject:result forKey:@(blur)];
        [self.blurAmountsBeingRendered removeObject:@(blur)];
        dispatch_async(dispatch_get_main_queue(), ^{
            [self imageIsAvailableWithBlur:blur];
        });
    });
}

-(void)imageIsAvailableWithBlur:(CGFloat)blurAmount {
    CGFloat smaller = self.blurRadius - fmodf(self.blurRadius, BLUR_STEP);
    CGFloat larger = smaller + BLUR_STEP;

    UIImage *sharperImage = [self cachedImageWithBlurAmount:smaller];
    UIImage *blurrier = [self cachedImageWithBlurAmount:larger];
    if(sharperImage && blurrier) {
        if(![self.imageView.image isEqual:sharperImage])
            self.imageView.image = sharperImage;
        if(![self.imageView2.image isEqual:blurrier]) {
            self.imageView2.image = blurrier;
        }
        self.imageView2.alpha = (self.blurRadius - smaller) / BLUR_STEP;
    }
}


@end

      

+7


source







All Articles