web-dev-qa-db-fra.com

Créer un effet de flou dans iOS7

Je cherchais une réponse à cette question depuis quelques heures maintenant, et je ne peux tout simplement pas le comprendre. Je veux ajouter un effet de flou gaussien à l'image lorsque j'appuie sur le bouton "Bouton". L'utilisateur est celui qui ajoute l'image.

J'ai créé une action pour le "Bouton" basée sur des sources de SO et d'autres endroits sur le web. Cela ne fonctionnera pas. Que fais-je de mal? Tout code serait grandement apprécié. Ici est mon action "Button":

- (IBAction)test:(id)sender {
    CIFilter *gaussianBlurFilter = [CIFilter filterWithName: @"CIGaussianBlur"];
    [gaussianBlurFilter setValue:imageView.image forKey: @"inputImage"];
    [gaussianBlurFilter setValue:[NSNumber numberWithFloat: 10] forKey: @"inputRadius"];
}

Si vous avez besoin d'autre chose que j'ai fait pour répondre à la question, veuillez me le faire savoir: D

Here is my UI

26
user2891448

Trois constats:

  1. Vous devez définir le inputImage pour qu'il soit le CIImage de votre UIImage:

    [gaussianBlurFilter setValue:[CIImage imageWithCGImage:[imageView.image CGImage]] forKey:kCIInputImageKey];
    
  2. Je ne vous vois pas saisir le outputImage, par exemple:

    CIImage *outputImage = [gaussianBlurFilter outputImage];
    
  3. Et vous voulez probablement reconvertir ce CIImage en un UIImage.

Donc, en rassemblant tout cela:

CIFilter *gaussianBlurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
[gaussianBlurFilter setDefaults];
CIImage *inputImage = [CIImage imageWithCGImage:[imageView.image CGImage]];
[gaussianBlurFilter setValue:inputImage forKey:kCIInputImageKey];
[gaussianBlurFilter setValue:@10 forKey:kCIInputRadiusKey];

CIImage *outputImage = [gaussianBlurFilter outputImage];
CIContext *context   = [CIContext contextWithOptions:nil];
CGImageRef cgimg     = [context createCGImage:outputImage fromRect:[inputImage extent]];  // note, use input image extent if you want it the same size, the output image extent is larger
UIImage *image       = [UIImage imageWithCGImage:cgimg];
CGImageRelease(cgimg);

Sinon, si vous accédez à exemple de code WWDC 201 (abonnement développeur payant requis) et téléchargez iOS_UIImageEffects, Vous pouvez alors saisir la catégorie UIImage+ImageEffects. Cela fournit quelques nouvelles méthodes:

- (UIImage *)applyLightEffect;
- (UIImage *)applyExtraLightEffect;
- (UIImage *)applyDarkEffect;
- (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor;
- (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage;

Donc, pour brouiller l'image et l'éclaircir (en donnant cet effet de "verre dépoli"), vous pouvez alors faire:

UIImage *newImage = [image applyLightEffect];

Fait intéressant, le code d'Apple n'utilise pas CIFilter, mais appelle plutôt vImageBoxConvolve_ARGB8888 du framework de traitement d'image haute performance vImage .

Cette technique est illustrée dans la vidéo WWDC 2013 Implémentation de l'IU engageante sur iOS .


Je sais que la question concernait iOS 7, mais maintenant dans iOS 8, on peut ajouter un effet de flou à n'importe quel objet UIView avec UIBlurEffect:

UIVisualEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:effect];    
effectView.frame = imageView.bounds;
[imageView addSubview:effectView];
74
Rob

Cela a fonctionné pour moi, mais c'est lent. Je ferai la transformation lors du chargement de l'application et utiliserai l'image transformée une fois dans de nombreux endroits.

Cet effet de flou est pour iOS 8.4. Swift langue.

override func viewDidLoad()
{
    super.viewDidLoad()

    var backgroundImage = self.blurImage(UIImage(named: "background.jpg")!)

    self.view.backgroundColor = UIColor(patternImage:backgroundImage)
}

func blurImage(imageToBlur:UIImage) -> UIImage
{
    var gaussianBlurFilter = CIFilter(name: "CIGaussianBlur")
    gaussianBlurFilter.setValue(CIImage(CGImage: imageToBlur.CGImage), forKey:kCIInputImageKey)

    var inputImage = CIImage(CGImage: imageToBlur.CGImage)

    var outputImage = gaussianBlurFilter.outputImage
    var context = CIContext(options: nil)
    var cgimg = context.createCGImage(outputImage, fromRect: inputImage.extent())

    return UIImage(CGImage: cgimg)!
}
4
MB_iOSDeveloper

L'entrée d'un CIFilter doit être un CIImage et non un UIImage.

1
rjstelling

Swift 4UIImage extension sans dépliage forcé:

extension UIImage {
    /// Applies a gaussian blur to the image.
    ///
    /// - Parameter radius: Blur radius.
    /// - Returns: A blurred image.
    func blur(radius: CGFloat = 6.0) -> UIImage? {
        let context = CIContext()
        guard let inputImage = CIImage(image: self) else { return nil }

        guard let clampFilter = CIFilter(name: "CIAffineClamp") else { return nil }
        clampFilter.setDefaults()
        clampFilter.setValue(inputImage, forKey: kCIInputImageKey)

        guard let blurFilter = CIFilter(name: "CIGaussianBlur") else { return nil }
        blurFilter.setDefaults()
        blurFilter.setValue(clampFilter.outputImage, forKey: kCIInputImageKey)
        blurFilter.setValue(radius, forKey: kCIInputRadiusKey)

        guard let blurredImage = blurFilter.value(forKey: kCIOutputImageKey) as? CIImage,
            let cgImage = context.createCGImage(blurredImage, from: inputImage.extent) else { return nil }

        let resultImage = UIImage(cgImage: cgImage, scale: scale, orientation: imageOrientation)
        return resultImage
    }
}

Je recommande fortement de brouiller l'image sur le fil d'arrière-plan:

let image = UIImage(named: "myImage")
DispatchQueue.global(qos: .userInitiated).async {
    let blurredImage = image.blur()
    DispatchQueue.main.async {
        self.myImageView.image = blurredImage
    }
}
1
Andrey Gordeev

Swift 2.

Faites une extension de UIImageView. (File-New-File-Empty Swift File -Name it Extensions.)

import Foundation
import UIKit

extension UIImageView{

 //Method 1
 func makeBlurImage(targetImageView:UIImageView?)
 {
  let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Dark)
  let blurEffectView = UIVisualEffectView(effect: blurEffect)
  blurEffectView.frame = targetImageView!.bounds

  blurEffectView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight] // for supporting device rotation
  targetImageView?.addSubview(blurEffectView)
 }
 //Method 2
 func convertToBlurImage(imageToBlur:UIImage) -> UIImage
 {
  let gaussianBlurFilter = CIFilter(name: "CIGaussianBlur")
  gaussianBlurFilter!.setValue(CIImage(CGImage: imageToBlur.CGImage!), forKey:kCIInputImageKey)

  let initialImage = CIImage(CGImage: imageToBlur.CGImage!)

  let finalImage = gaussianBlurFilter!.outputImage
  let finalImagecontext = CIContext(options: nil)

  let finalCGImage = finalImagecontext.createCGImage(finalImage!, fromRect: initialImage.extent)
  return UIImage(CGImage: finalCGImage)
 }
}

tilisation:

En utilisant la méthode 1:

override func viewDidLoad() {
  super.viewDidLoad()

  let sampleImageView = UIImageView(frame: CGRectMake(0, 200, 300, 325))
  let sampleImage:UIImage = UIImage(named: "ic_120x120")!
  sampleImageView.image =  sampleImage

  //Convert To Blur Image Here
  sampleImageView.makeBlurImage(sampleImageView)

  self.view.addSubview(sampleImageView)
 }

En utilisant la méthode 2:

   override func viewDidLoad() {
      super.viewDidLoad()

      let sampleImageView = UIImageView(frame: CGRectMake(0, 200, 300, 325))
      let sampleImage:UIImage = UIImage(named: "ic_120x120")!

      //Convert to Blurred Image Here
      let sampleImage2 =  sampleImageView.convertToBlurImage(sampleImage)
      sampleImageView.image =  sampleImage2

      self.view.addSubview(sampleImageView)
     }
0
A.G

Voici une extension pour le flou de l'image sur

Swift

extension UIImage {

    public func blurImage(radius: CGFloat) -> UIImage {

        let inputImage = CIImage(image: self)!

        let parameters: [String:Any] = [
            kCIInputRadiusKey: radius,
            kCIInputImageKey: inputImage
        ]
        let filter = CIFilter(name: "CIGaussianBlur",
                              withInputParameters: parameters)!

        let cgimg = CIContext().createCGImage(filter.outputImage!, from: inputImage.extent)
        return UIImage(cgImage: cgimg!)
    }

}
0
Alex Shubin