5

アプリで行っているガウスぼかしがあります。

    //Get a UIImage from the UIView
    UIGraphicsBeginImageContext(self.view.bounds.size);
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    //Blur the UIImage
    CIImage *imageToBlur = [CIImage imageWithCGImage:viewImage.CGImage];
    CIFilter *gaussianBlurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
    [gaussianBlurFilter setValue:imageToBlur forKey:@"inputImage"];
    [gaussianBlurFilter setValue:[NSNumber numberWithFloat:2] forKey:@"inputRadius"];
    CIImage *resultImage = [gaussianBlurFilter valueForKey:@"outputImage"];
    UIImage *endImage = [[UIImage alloc] initWithCIImage:resultImage];

    //Place the UIImage in a UIImageView
    newView = [[UIImageView alloc] initWithFrame:self.view.bounds];
    newView.image = endImage;
    [self.view addSubview:newView];

うまく機能しますが、元に戻してビューを通常に戻すことができるようにしたいと思います。

スーパービューからブラーのビューを単純に削除しようとしても機能しなかったため、これを行うにはどうすればよいですか。また、運が悪かったので、さまざまなプロパティをnilに設定してみました。

4

3 に答える 3

3

プロパティにviewImageへのポインタを保持します

@property (nonatomic, strong) UIImage* originalImage;

後で

UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();

追加

self.originalImage = viewImage;

画像を元に戻すには:

newView.image = self.originalImage;

ぼかしを適用しても、viewImageは変更されません。ぼやけた別のCIImageを作成し、ぼやけたCIImageから新しいUIImageを作成します。

于 2013-01-25T06:17:10.057 に答える
1
  • 私があなたのコードで最初に見たのは、非同期タスクでフィルターを適用しないということです。画像をぼかすには時間がかかるため、メインスレッドをフリーズしたくない場合は、次を使用する必要があります。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    //blur the image in a second thread
    dispatch_async(dispatch_get_main_queue(), ^{
        //set the blurred image to your imageView in the main thread
    });
});

  • 元の画像を元に戻すには、元の画像の上に表示される他のimageViewにぼやけたコピーを配置するだけです。私の場合、元の画像はimageViewではなく、ビュー自体です。そのため、ビューにimageViewを追加してぼやけた画像を設定し、反転する場合はnilに設定します。

  • 最後に、ぼやけた画像を設定するときに点滅を避けたい場合は、アニメーションでアルファを使用してソフトトランジションを作成できます。

[self.blurredImageView setAlpha: 0.0]; //make the imageView invisible
[self.blurredImageView setImage:blurredImage];
//and after set the image, make it visible slowly.
[UIView animateWithDuration:0.5 delay:0.1
                            options:UIViewAnimationOptionCurveEaseInOut
                         animations:^{
                             [self.blurredImageView setAlpha: 1.0]; 
                         }
                         completion:nil];

  • これが私の完全な方法です:

- (void)makeBlurredScreenShot{
    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0);
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *imageView = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    CIContext *context   = [CIContext contextWithOptions:nil];
    CIImage *sourceImage = [CIImage imageWithCGImage:imageView.CGImage];

    // Apply clamp filter:
    // this is needed because the CIGaussianBlur when applied makes
    // a trasparent border around the image
    NSString *clampFilterName = @"CIAffineClamp";
    CIFilter *clamp = [CIFilter filterWithName:clampFilterName];
    if (!clamp)
        return;

    [clamp setValue:sourceImage forKey:kCIInputImageKey];
    CIImage *clampResult = [clamp valueForKey:kCIOutputImageKey];

    // Apply Gaussian Blur filter
    NSString *gaussianBlurFilterName = @"CIGaussianBlur";
    CIFilter *gaussianBlur           = [CIFilter filterWithName:gaussianBlurFilterName];
    if (!gaussianBlur)
        return;

    [gaussianBlur setValue:clampResult forKey:kCIInputImageKey];
    [gaussianBlur setValue:[NSNumber numberWithFloat:8.0] forKey:@"inputRadius"];

    CIImage *gaussianBlurResult = [gaussianBlur valueForKey:kCIOutputImageKey];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        CGImageRef cgImage = [context createCGImage:gaussianBlurResult fromRect:[sourceImage extent]];

        UIImage *blurredImage = [UIImage imageWithCGImage:cgImage];
        CGImageRelease(cgImage);

        dispatch_async(dispatch_get_main_queue(), ^{
            [self.blurredImageView setAlpha: 0.0];
            [self.blurredImageView setImage:blurredImage];
            [UIView animateWithDuration:0.5 delay:0.1
                                options:UIViewAnimationOptionCurveEaseInOut
                             animations:^{
                                 [self.blurredImageView setAlpha: 1.0]; 
                             }
                             completion:nil];
        });
    });
}

- (void)removeBlurredScreenShot{
    [UIView animateWithDuration:0.5 delay:0.1
                        options:UIViewAnimationOptionCurveEaseInOut
                     animations:^{
                          [self.blurredImageView setAlpha: 0.0];
                             }
                     completion:^(BOOL finished) {
                          [self.blurredImageView setImage:nil];
                     }];
}
于 2014-04-11T08:10:14.040 に答える
0

以前のコメントで述べたように、エフェクトが適用される前に画像を保持するプロパティ/ iVarを作成し、元に戻したい場合に元に戻すことができます。

if(!_originalImage)
    _originalImage = [[UIImage alloc] init];

_originalImage = viewImage; //(Creates a copy, not a C-Type pass-by-reference)

// Do your Blur Stuff

// Now somewhere down the line in your program, if you don't like the blur and the user would like to undo:

viewImage = _originalImage;

@HeWasの回答に対するコメントによると、ビューを完全にぼかすことはできません。ビューがぼやけている場合は、プログラムの他の場所で間違っていることがあります。

于 2013-01-25T16:40:55.233 に答える