2013-10-17 53 views
26

我在几个小时内一直在寻找这个问题的答案,但我无法弄清楚。当我按下按钮“Button”时,我想为图像添加一个高斯模糊效果。用户是添加图像的用户。在iOS7中创建模糊效果

我已经基于来自SO和网络上其他地方的资源创建了“按钮”的操作。不起作用。我究竟做错了什么?任何代码将不胜感激。这是我的“按钮”操作:

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

如果你有什么事,我已经做了回答这个问题,请让我知道:d

Here is my UI

回答

72

三点意见:

  1. 您需要设置inputImage成为了CIImageUIImage

    [gaussianBlurFilter setValue:[CIImage imageWithCGImage:[imageView.image CGImage]] forKey:kCIInputImageKey]; 
    
  2. 我没有看到你抓住outputImage,如:

    CIImage *outputImage = [gaussianBlurFilter outputImage]; 
    
  3. 而你可能想将CIImage转换回UIImage

因此,把所有在一起:

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

或者,如果你去WWDC 2013 sample code(需付费开发商订阅),并下载iOS_UIImageEffects,然后你可以抓住UIImage+ImageEffects类别。这提供了一些新的方法:

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

所以,模糊和图像,并减轻它(让说:“磨砂玻璃”的效果),那么你可以这样做:

UIImage *newImage = [image applyLightEffect]; 

有趣的是,苹果公司的代码做不是雇用CIFilter,而是拨打vImage high-performance image processing frameworkvImageBoxConvolve_ARGB8888

该技术在WWDC 2013视频Implementing Engaging UI on iOS中进行了说明。


我知道这个问题是关于iOS的7,但现在在iOS 8的一个可以添加一个模糊效果的任何UIView对象与UIBlurEffect

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

让说我在ibaction没有任何代码,什么exca tcly我会写在我的ibaction吗?它是你写的最后一段代码吗?感谢btw的一个很好的回复,并且对于理解不够深感抱歉:D – user2891448

+0

我现在看到了您最后编辑的答案,谢谢! – user2891448

+0

我得到一个警告,“未使用的变量图像”,这是代码 – user2891448

1

CIFilter需要输入成为CIImage而不是UIImage

4

这为我工作,但它是缓慢的。我将在应用程序加载上进行转换,并在很多地方使用一次转换后的图像。

此模糊效果适用于iOS 8.4。 Swift语言。

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)! 
} 
+1

这是非常有趣的..但也很慢..:/ 至少在苹果电视 –

+0

是的,它很慢:/。你可以做“onDemand”模糊,这可能有帮助,或者如果你有一些在应用程序加载,然后调用blurImage函数。在某些时候,我保存了模糊的图像,所以当我需要它们时,我可以从内存或其他地方加载它们,而不是再次调用该函数。希望这会有所帮助,或者指出你正确的方向:))) –

0

夫特2.0

制作的UIImageView的延伸。 (文件 - 新建 - 文件 - 空斯威夫特文件-name它扩展。)

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

用法:

使用方法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) 
} 

使用方法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

这里是对图像模糊的扩展

夫特3

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

夫特4UIImage延伸而不力解缠:

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

我强烈建议模糊在后台线程的图像:

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