2

だから、私は奇妙なシナリオを持っています。

私の iOS アプリでは、ポップオーバーが開いたときに画面のコンテンツ領域をぼかしようとしています。Core Image を使用している場合はこれが機能しますが、Gaussian ブラーを使用している場合のみです。他のブラーはどれも機能しません。これは奇妙です。

私は 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

そして、私のView Controllerでは、単に呼び出されます

[ScreenBlur setBlurOnView:self.view];
4

1 に答える 1

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];
于 2013-08-15T20:00:24.210 に答える