iOS - 在其他视图之上设置模糊图像,奇怪的问题

时间:2013-08-15 18:04:19

标签: ios objective-c cocoa-touch gpuimage

所以,我有一个奇怪的情况。

在我的iOS应用中,我试图在打开弹出窗口时模糊屏幕的内容区域。 我在使用Core Image时有这个工作,但只有在使用高斯模糊时 - 其他模糊都没有用,这很奇怪。

我尝试使用GPUImage做同样的事情,并且它的速度更快,但实际上并没有将视图置于其他视图之上!

总结一下:在下面的源代码中,setBlurOnView将正常工作 - 但是setBlurOnViewWithGPUImage似乎无法正常工作。创建了模糊视图(标记6110),但应用程序实际上并未模糊。

注意:这是在iOS 6的模拟器中。

以下是相关来源:

//  ScreenBlur.m

#import <QuartzCore/QuartzCore.h>
#import <CoreImage/CoreImage.h>
#import <GPUImage/GPUImage.h>

#import "ScreenBlur.h"
#import "GlobalData.h"
#import "Logger.h"

@implementation ScreenBlur

+ (void) setBlurOnViewWithGPUImage:(UIView*)view {
    GPUImagePicture *imageSource = [[GPUImagePicture alloc] initWithImage:[self captureScreenInRect:view.frame inView:view]];
    GPUImageGaussianBlurFilter *blur = [[GPUImageGaussianBlurFilter alloc] init];

    [imageSource addTarget:blur];
    [imageSource processImage];

    [self setImage:[imageSource imageFromCurrentlyProcessedOutput] toView:view];
}

+ (void) setBlurOnView:(UIView *)view {
    //http://stackoverflow.com/questions/17041669/creating-a-blurring-overlay-view

    CIImage *inputImage = [CIImage imageWithCGImage:[self captureScreenInRect:view.frame inView:view].CGImage];
    //CIContext *context = [CIContext contextWithOptions:nil];
    if ([GlobalData getInstance].ciContext == nil) {
        [Logger Log:@"ciContext does not exist, creating..." fromClass:@"ScreenBlur"];
//        [GlobalData getInstance].ciContext = [CIContext contextWithOptions:nil]; //cpu context
        [GlobalData getInstance].ciContext = [CIContext contextWithEAGLContext:[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]];
    }


    //set up the blur filter
    CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
    [filter setValue:inputImage forKey:kCIInputImageKey];
    [filter setValue:[NSNumber numberWithFloat:3.0f] forKey:@"inputRadius"];
    CIImage *result = [filter valueForKey:kCIOutputImageKey];

    // CIGaussianBlur has a tendency to shrink the image a little,
    // this ensures it matches up exactly to the bounds of our original image
    CGImageRef cgImage = [[GlobalData getInstance].ciContext createCGImage:result fromRect:[inputImage extent]];

    [self setImage:[UIImage imageWithCGImage:cgImage] toView:view];
}

+ (void) setImage:(UIImage*)blurredImage toView:(UIView*)view {
    UIView *blurView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, blurredImage.size.width, blurredImage.size.height)];
    [blurView setBackgroundColor:[UIColor colorWithPatternImage:blurredImage]];
    [blurView setTag:6110];

    //set the image as the foreground for the view
    [view addSubview:blurView];
    [view bringSubviewToFront:blurView];
}

//same as the method above, but resizes the screenshot before applying the blur for increased performance at the expense of image quality.
+ (void) setBlurOnViewPerformanceMode:(UIView *)view {
    //http://stackoverflow.com/questions/17041669/creating-a-blurring-overlay-view

    UIImage *screenShot = [self imageWithImage:[self captureScreenInRect:view.frame inView:view] scaledToSize:CGSizeMake(view.frame.size.width / 2, view.frame.size.height / 2)];
    CIImage *inputImage = [CIImage imageWithCGImage:screenShot.CGImage];
    //CIContext *context = [CIContext contextWithOptions:nil];
    if ([GlobalData getInstance].ciContext == nil) {
        [Logger Log:@"ciContext does not exist, creating..." fromClass:@"ScreenBlur"];
        //        [GlobalData getInstance].ciContext = [CIContext contextWithOptions:nil]; //cpu context
        [GlobalData getInstance].ciContext = [CIContext contextWithEAGLContext:[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]];
    }

    //set up the blur filter
    CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
    [filter setValue:inputImage forKey:kCIInputImageKey];
    [filter setValue:[NSNumber numberWithFloat:3.0f] forKey:@"inputRadius"];
    CIImage *result = [filter valueForKey:kCIOutputImageKey];

    //CGImageRef cgImage = [[GlobalData getInstance].ciContext createCGImage:result fromRect:[inputImage extent]];
    CGImageRef cgImage = [[GlobalData getInstance].ciContext createCGImage:result fromRect:[inputImage extent]];

    [self setImage:[self imageWithImage:[UIImage imageWithCGImage:cgImage] scaledToSize:view.frame.size] toView:view];
}

+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
    //UIGraphicsBeginImageContext(newSize);
    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}


+ (void) removeBlurFromView:(UIView *)view {
    for (UIView *subView in view.subviews) {
        if (subView.tag == 6110) {
            [subView removeFromSuperview];
        }
    }
}

+ (UIImage *)captureScreenInRect:(CGRect)captureFrame inView:(UIView*) view {
    CALayer *layer;
    layer = view.layer;
    UIGraphicsBeginImageContext(view.bounds.size);
    CGContextClipToRect (UIGraphicsGetCurrentContext(),captureFrame);
    [layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return screenImage;
}

@end

然后在我的视图控制器中,它只是用

调用
[ScreenBlur setBlurOnView:self.view];

1 个答案:

答案 0 :(得分:0)

我找到了一个解决方法(或者,谁知道,也许这是应该如何完成的。)

//ScreenBlur.m
+ (GPUImageView*) getBlurredImageWithGPUImageFromView:(UIView*)view {
    GPUImagePicture *imageSource = [[GPUImagePicture alloc] initWithImage:[self captureScreenInRect:view.frame inView:view] smoothlyScaleOutput:true];

    GPUImageFastBlurFilter *blur = [[GPUImageFastBlurFilter alloc] init];
    [blur setBlurPasses:3];

    [imageSource addTarget:blur];

    GPUImageView *filteredView = [[GPUImageView alloc] initWithFrame:view.frame];
    [blur addTarget:filteredView];

    [imageSource processImage];


    return filteredView;
}

//ViewController.m
//blur the main screen
GPUImageView *blurred = [ScreenBlur getBlurredImageWithGPUImageFromView:self.view];
[blurred setTag:6110];
[self.view addSubview:blurred];
[self.view bringSubviewToFront:blurred];