2013-01-25 16 views
5

Mam rozmycie gaussowskie, które robię dla aplikacji.Odwrócenie filtru rozmycia Gaussa: iOS

//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]; 

Działa wspaniale, ale chcę mieć możliwość odwrócenia go i przywrócenia widoku do normalności.

W jaki sposób mogę to zrobić, próbując po prostu usunąć widok rozmycia, jego widok nie działa. Próbowałem również ustawić różne właściwości do zerowania bez powodzenia.

+0

nie można po prostu zrobić kopię viewImage przed rozmycie jest stosowana i powrócić, jeśli chcesz odwrócić? – Ravi

+0

Jak zrobić kopię bez zmiany obu kopii po zastosowaniu efektu rozmycia? – jakenberg

Odpowiedz

3

przechowywać wskaźnik do viewImage w nieruchomości

@property (nonatomic, strong) UIImage* originalImage; 

wtedy po

UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext(); 

dodać

self.originalImage = viewImage; 

Aby przywrócić swój obraz:

newView.image = self.originalImage; 

po zastosowaniu rozmycia nie zmienia viewImage ... utworzyłeś osobny CIImage, który się rozmywa, i robisz nowy UIImage z niewyraźnego CIImage.

+0

Uświadomiłem sobie, że to, co robię ogólnie, jest nieprawidłowe. Próbuję sprawić, że moje self.view rozmycie, ponieważ tymczasowo umieszczam niektóre obiekty na wierzchu. Nie chcę oryginalnego obrazu, ale zamiast tego wracam do widoku, w którym byłem pierwotnie. Twoja odpowiedź jest prawidłowa, ale czy uważasz, że możesz edytować swoją odpowiedź, aby to odzwierciedlić? Chciałbym dać ci dwa znaczniki wyboru: P – jakenberg

+0

Skończyłem właśnie tworząc UIView z rozmyciem na nim, a następnie pozbywając się go w ten sposób. Dziękuję Ci! – jakenberg

0

Tak jak powiedziałem w poprzednim komentarzu, można utworzyć właściwość/iVar, która przechowuje obraz przed zastosowaniem efektu i powrócić w przypadku cofnięcia.

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; 

Zgodnie z komentarzem do odpowiedzi @ HeWas nie należy całkowicie zamazywać widoku. Jeśli widok się zaciera, jest coś, co robisz źle w innym miejscu programu.

1
  • Pierwszą rzeczą, którą zobaczyłem w twoim kodzie jest to, że nie stosujesz filtra w zadaniu asynchronicznym. rozmycie obrazu czasu podjęcia, więc jeśli nie chcesz zamrażać główny wątek powinien użyć:

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 
    }); 
}); 

  • Aby można odwrócić obraz oryginalny, wystarczy umieścić zamazana kopia w innym obrazie, który pojawia się nad oryginałem. W moim przypadku oryginalny obraz nie jest obrazem, ale sam widok. Dlatego dodam tylko obraz w moim widoku, aby ustawić zamazany obraz i ustawić wartość zerową, gdy chcę cofnąć.

  • Wreszcie, jeśli chcesz uniknąć migać po ustawieniu zamazany obraz, można grać z alfa w animacji dokonania miękkie przejście:

[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]; 

  • Oto moja com Metody zyć:

- (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]; 
        }]; 
}