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
Trois constats:
Vous devez définir le inputImage
pour qu'il soit le CIImage
de votre UIImage
:
[gaussianBlurFilter setValue:[CIImage imageWithCGImage:[imageView.image CGImage]] forKey:kCIInputImageKey];
Je ne vous vois pas saisir le outputImage
, par exemple:
CIImage *outputImage = [gaussianBlurFilter outputImage];
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];
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)!
}
L'entrée d'un CIFilter
doit être un CIImage
et non un UIImage
.
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
}
}
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)
}
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!)
}
}