本文介绍了GPUImage动画高斯模糊滤镜的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用GPUImage高斯模糊滤镜来模糊静止图像.我想将模糊大小绑定到UI元素,并且当用户更改该元素时,我会模糊图片.我现在的操作方式是在发生重大变化(> 0.25)时更改blurSize,重新应用滤镜并将新图像设置为imageView的动画.

I was using the GPUImage gaussian blur filter to blur a still image. I want to tie the blur size to an UI element and as the element is changed by the user I blur the picture. The way I am doing it right now is to change the blurSize when there has been a significant (> 0.25) change, reapply the filter and animate the new image into the imageView.

我是否有更有效的方法来执行此操作?

Is there a more efficient way for me to be doing this?

在iPhone 5上,虽然性能也不差,但也不是超级平滑(但这也许是因为此操作过于昂贵,无法实现超级平滑).

On the iPhone 5, while performance is not laggy, it is not super smooth either (but perhaps that is because this operation is simply too expensive to be super smooth).

推荐答案

有趣的问题.最好的选择是在您的范围内以几个模糊比例预先计算和渲染CGImage,然后使用两个堆叠的UIImageView,最上面的一个显示模糊副本,但部分透明.例如,如果以1、2、3,…,10的半径渲染了模糊的图像,并且想要显示3.7,则在底部显示图像3,在顶部显示图像4,不透明度为70%.

interesting question. Your best bet is to pre-compute and render CGImages at a couple of blur scales in your range, then use two stacked UIImageViews, with the one on top showing the blurrier copy but partially transparent. For example, if you rendered blurred at radiuses 1,2,3,…,10, and you wanted to show 3.7, you'd show image 3 on the bottom and image 4 on the top, at 70% opacity.

// Created in answer to Nikhil Varma's 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's 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

这篇关于GPUImage动画高斯模糊滤镜的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 06:13