iOS中实现模糊效果(附带多种滤镜探索,你值得转载)

转载:http://www.jianshu.com/p/63ba42ea8d41 然后进行二次加工

iOS中实现模糊效果

字数1403 阅读228 评论0 

iOS中实现模糊效果的方法有多种,本文介绍两种。

1. 使用CoreImage实现

CoreImage框架最早出现于iOS5,后期苹果又对这个框架进行了扩展。
CoreImage框架中的常用类: 

  1. CIImage:代表图片的对象。 
  2. CIFilter:代表滤镜的对象,通过key/value的方式设置参数。 
  3. CIContext:用来渲染CIImage 。 

下面我们来看看简单它的简单使用。

  1. 创建CIImage对象。

     - (CIImage *)ciImage
     {
         if (!_ciImage) {
             _ciImage = [[CIImage alloc]initWithImage:[UIImage imageNamed:@"image"]];
         }
         return _ciImage;
     }
  2. 创建CIFilter滤镜对象。

     - (CIFilter *)filter
     {
         if (!_filter) {
             //传入滤镜的名字即可使用类方法创建                
             _filter = [CIFilter filterWithName:@"CIGaussianBlur"];
         }
         return _filter;
     }

    现在的SDK中包含了很多种滤镜,那么我们怎么知道具体有哪些滤镜呢?又怎么知道每一种滤镜的具体用法呢?百度?谷歌?当然可以,但是还有另一种方法。
    我们从CIFilter的头文件中可以看到滤镜有很多种分类,名字都是以kCICategory...开头,我们可以通过CIFilter的类方法得到对应分类下的所有滤镜。以kCICategoryBuiltIn为例,获取这个分类下的滤镜:

     NSArray *filters = [CIFilter filterNamesInCategory:kCICategoryBuiltIn];
     NSLog(@"filters = %@",filters);
     //打印出来
     filters = (
         CIAccordionFoldTransition,
         CIAdditionCompositing,
         CIAffineClamp,
         CIAffineTile,
         CIAffineTransform,
         .....
     }

    选择好自己需要的滤镜之后,再通过查看滤镜的属性来了解它的用法。以高斯模糊滤镜为例:

     _filter = [CIFilter filterWithName:@"CIGaussianBlur"];
     NSLog(@"attribute = %@",[_filter attributes]);

    打印的结果

     attribute = {
         "CIAttributeFilterAvailable_Mac" = "10.4";
         "CIAttributeFilterAvailable_iOS" = 6;
         CIAttributeFilterCategories =     (
                                            CICategoryBlur,
                                            CICategoryStillImage,
                                            CICategoryVideo,
                                            CICategoryBuiltIn
                                            );
         CIAttributeFilterDisplayName = "Gaussian Blur";
         CIAttributeFilterName = CIGaussianBlur;
         CIAttributeReferenceDocumentation = "http://developer.apple.com/cgi-bin/apple_ref.cgi?apple_ref=//apple_ref/doc/filter/ci/CIGaussianBlur";
         inputImage =     {
             CIAttributeClass = CIImage;
             CIAttributeDescription = "The image to use as an input image. For filters that also use a background image, this is the foreground image.";
             CIAttributeDisplayName = Image;
             CIAttributeType = CIAttributeTypeImage;
         };
         inputRadius =     {
             CIAttributeClass = NSNumber;
             CIAttributeDefault = 10;    //默认模糊度为10
             CIAttributeDescription = "The radius determines how many pixels are used to create the blur. The larger the radius, the blurrier the result.";
             CIAttributeDisplayName = Radius;
             CIAttributeIdentity = 0;
             CIAttributeMin = 0;
             CIAttributeSliderMax = 100;    //最高模糊度100
             CIAttributeSliderMin = 0;     //最低模糊度0
             CIAttributeType = CIAttributeTypeScalar;
         };
     }

    大概说一下高斯模糊滤镜的属性,也是设置滤镜相关参数时的key:
    CIAttributeFilterAvailable_iOS:iOS最低可用系统版本。
    CIAttributeFilterCategories:该滤镜所属分类。
    inputImage:输入的图像为CIImage对象。
    inputRadius:模糊程度的参数,类型为NSNumber,默认模糊度为10,最低0,最高100。
    了解了这几个属性使用高斯模糊就没问题了。

  3. 创建CIContext对象。
    在iOS平台下创建CIContext的方式有多种,这里介绍两种。

    1. 创建基于CPU的CIContext对象:

       _context = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer:@(YES)}];
    2. 创建基于GPU的CIContext对象。

       _context = [CIContext contextWithOptions:nil];

      采用基于GPU的CIContext将可以获得更好的性能,但是基于GPU创建的CIContext跨应用使用时会自动降为基于CPU的。比如,在进入相册选择相片的时候,如果在UIImagePickerControllerDelegate的代理方法中使用CIContext对象处理图像,系统就会把这个任务交给CPU做。

  4. 三个对象创建好之后就可以对图像做处理了。

     //设置滤镜输入的图像
     //注意:这里的key可以写kCIInputImageKey,也可以写@“inputImage”
     [self.filter setValue:self.ciImage forKey:kCIInputImageKey];
     //设置高斯模糊的模糊程度
     //这里的key可以写kCIInputRadiusKey,也可以写@“inputRadius”。
     [self.filter setValue:@(value) forKey:kCIInputRadiusKey];
    
     //得到处理后的图片
     CIImage *outImage = [self.filter valueForKey:kCIOutputImageKey];
    
     CGImageRef cgImage = [self.context createCGImage:outImage fromRect:[outImage extent]];
     //显示图片
     self.blurImage.image = [UIImage imageWithCGImage:cgImage];
     CGImageRelease(cgImage);

效果图如下


2. 使用UIVisualEffectView实现

UIVisualEffectView是iOS8开放的接口,使用比较简单。大概用法就是创建一个UIVisualEffectView的视图,将其放于需要添加blur效果的视图上面即可。
我们举个例子来看看UIVisualEffectView的简单使用。

UIImage *image = [UIImage imageNamed:@"1.jpg"];
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
imageView.image = image;
[scrollView addSubview:imageView];
scrollView.contentSize = image.size;

//blurView
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight];
UIVisualEffectView *visualEffectView = [[UIVisualEffectView alloc]initWithEffect:blurEffect];
visualEffectView.frame = CGRectMake(0, 0, self.view.frame.size.width, 300);
[self.view addSubview:visualEffectView];

这段代码在scorllView上添加了一张大图,然后在scrollView上添加了一个blur效果视图。可以看出UIVisualEffectView的使用方法还是很简单的。 

  1. UIVisualEffectView初始化的时候需要以一个UIVisualEffect对象为参数,但是通过查看它的头文件发现它并没有除继承自NSObject之外的属性和方法。但是它又两个子类UIBlurEffectUIVibrancyEffect,我们可以传入这两个子类的对象来初始化UIVisualEffectView。 
  2. UIBlurEffect:看其名字就知道它是用来实现模糊效果的。创建的模糊效果有三种风格: 
UIBlurEffectStyleExtraLight,
UIBlurEffectStyleLight,
UIBlurEffectStyleDark

3.UIVibrancyEffect:主要用于让处于UIVisualEffectView上的内容看起来更加生动,它需要和UIBlurEffect一起使用。接上面的代码,我们在blur视图上面添加一张图片,并让图片显示也会有特殊效果,如下代码:

//创建UIVibrancyEffect对象
UIVibrancyEffect *vibrancyEffect = [UIVibrancyEffect effectForBlurEffect:blurEffect];
UIVisualEffectView *vibrancyEffectView = [[UIVisualEffectView alloc]initWithEffect:vibrancyEffect];
vibrancyEffectView.frame = visualEffectView.bounds;
//将有UIVibrancyEffect效果的视图添加到visualEffectView.contentView上
[visualEffectView.contentView addSubview:vibrancyEffectView];
//添加图片    
UIImage *logoImage = [UIImage imageNamed:@"logo"];
UIImageView *logo = [[UIImageView alloc]initWithImage:logoImage];
logo.frame = CGRectMake(0, 0, logoImage.size.width, logoImage.size.height);
logo.center = visualEffectView.center;
[vibrancyEffectView.contentView addSubview:logo];

效果图如下:



<span style="font-size:12px;">/**
 *  滤镜
 */
- (CIFilter *)filter
{
    if (!_filter) {
        //查看某个分类下的所有滤镜
        NSArray *filters = [CIFilter filterNamesInCategory:kCICategoryBuiltIn];
        NSLog(@"filters = %@",filters);
        
        _filter = [CIFilter filterWithName:@"CIColorClamp"];
        //        //再通过打印该滤镜的详细信息来查看它的用法
        NSLog(@"attribute = %@",[_filter attributes]);
    }
    return _filter;
}

- (void)sliderValueChange:(UISlider *)slider
{
    CGFloat value = slider.value/100;
    //设置滤镜参数
    [self.filter setValue:self.ciImage forKey:kCIInputImageKey];
    CIVector*v=[[CIVector alloc]initWithCGRect:CGRectMake(value, value, value, value)
                ];
    [self.filter setValue:v forKey:@"inputMaxComponents"];
    

    //得到处理后的图片
    CIImage *outImage = [self.filter valueForKey:kCIOutputImageKey];
    
    CGImageRef cgImage = [self.context createCGImage:outImage fromRect:[outImage extent]];

    self.blurImage.image = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);

}
</span>

运行结果

/**
 *  滤镜
 */
- (CIFilter *)filter
{
    if (!_filter) {
        //查看某个分类下的所有滤镜
        NSArray *filters = [CIFilter filterNamesInCategory:kCICategoryBuiltIn];
        NSLog(@"filters = %@",filters);
        
        _filter = [CIFilter filterWithName:@"CICircularWrap"];
        //        //再通过打印该滤镜的详细信息来查看它的用法
        NSLog(@"attribute = %@",[_filter attributes]);
    }
    return _filter;
}
- (void)sliderValueChange:(UISlider *)slider
{
    CGFloat value = slider.value*6;
    //设置滤镜参数
    [self.filter setValue:self.ciImage forKey:kCIInputImageKey];
    [self.filter setValue:@(value) forKey:kCIInputRadiusKey];
    
    [self.filter setValue:@(value/600*3.14) forKey:kCIInputAngleKey];

    //得到处理后的图片
    CIImage *outImage = [self.filter valueForKey:kCIOutputImageKey];
    
    CGImageRef cgImage = [self.context createCGImage:outImage fromRect:[outImage extent]];

    self.blurImage.image = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);
}

运行结果

/**
 *  滤镜
 */
- (CIFilter *)filter
{
    if (!_filter) {
        //查看某个分类下的所有滤镜
        NSArray *filters = [CIFilter filterNamesInCategory:kCICategoryBuiltIn];
        NSLog(@"filters = %@",filters);
        
        _filter = [CIFilter filterWithName:@"CILineOverlay"];
        //        //再通过打印该滤镜的详细信息来查看它的用法
        NSLog(@"attribute = %@",[_filter attributes]);
    }
    return _filter;
}
- (void)sliderValueChange:(UISlider *)slider
{
    CGFloat value = slider.value/1000;
    //设置滤镜参数
    [self.filter setValue:self.ciImage forKey:kCIInputImageKey];
    [self.filter setValue:@(value) forKey:@"inputThreshold"];
    

    //得到处理后的图片
    CIImage *outImage = self.filter.outputImage;
    
    CGImageRef cgImage = [self.context createCGImage:outImage fromRect:[outImage extent]];

    self.blurImage.image = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);
}

运行结果:

/**
 *  滤镜
 */
- (CIFilter *)filter
{
    if (!_filter) {
        //查看某个分类下的所有滤镜
        NSArray *filters = [CIFilter filterNamesInCategory:kCICategoryBuiltIn];
        NSLog(@"filters = %@",filters);
        
        _filter = [CIFilter filterWithName:@"CIBarsSwipeTransition"];
        //        //再通过打印该滤镜的详细信息来查看它的用法
        NSLog(@"attribute = %@",[_filter attributes]);
    }
    return _filter;
}
- (void)sliderValueChange:(UISlider *)slider
{
    CGFloat value = slider.value/100;
    //设置滤镜参数
    [self.filter setValue:self.ciImage forKey:kCIInputImageKey];
    [self.filter setValue:@(value) forKey:kCIInputTimeKey];
    [self.filter setValue:@(value*100*3+2) forKey:kCIInputWidthKey];

    //得到处理后的图片
    CIImage *outImage = self.filter.outputImage;
    
    CGImageRef cgImage = [self.context createCGImage:outImage fromRect:[outImage extent]];

    self.blurImage.image = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);
}

运行结果

/**
 *  滤镜
 */
- (CIFilter *)filter
{
    if (!_filter) {
        //查看某个分类下的所有滤镜
        NSArray *filters = [CIFilter filterNamesInCategory:kCICategoryBuiltIn];
        NSLog(@"filters = %@",filters);
        
        _filter = [CIFilter filterWithName:@"CIBloom"];
        //        //再通过打印该滤镜的详细信息来查看它的用法
        NSLog(@"attribute = %@",[_filter attributes]);
    }
    return _filter;
}
- (void)sliderValueChange:(UISlider *)slider
{
    CGFloat value = slider.value;
    //设置滤镜参数
    [self.filter setValue:self.ciImage forKey:kCIInputImageKey];
    [self.filter setValue:@(value) forKey:kCIInputRadiusKey];
    [self.filter setValue:@(value/100) forKey:kCIInputIntensityKey];

    //得到处理后的图片
    CIImage *outImage = self.filter.outputImage;
    
    CGImageRef cgImage = [self.context createCGImage:outImage fromRect:[outImage extent]];

    self.blurImage.image = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);
}


如果你愿意探索,127中滤镜都在你手中

CoreImage推荐阅读:使用coreImage滤镜 
UIVisualEffectView推荐阅读:
使用UIVisualEffectView为视图添加特殊效果
iOS 8 UIVisualEffectView(注:日语写的,不过看看例子不错)


阅读更多
换一批

没有更多推荐了,返回首页