CIFilter iOS滤镜

来源:互联网 发布:js获取json的key 编辑:程序博客网 时间:2024/05/21 10:25

苹果为了用户的极致体验,在细节上面做了好多功课,光是为了视觉上面的体验,为开发者推出了好多图片滤镜,我就我自己的理解,简单的做一些分享!


一:CIFilter是对CIImage的操作,输入时CIImage,输出也是CIImage,但是我们平时大多数使用的都是UIImage或者CGImage,怎么转换呢?

UIImage的声明中有这么一句 

  @property(nullable,nonatomic,readonly)CIImage *CIImage NS_AVAILABLE_IOS(5_0);// returns underlying CIImage or nil if CGImageRef based

 我完整的复制出来了这一句,不要忽略"//"后面的注释内容,意思就是说如果这个UIImage是以CGImageRef为根基的,那么就返回nil,否则返回下面的CIImage。

而通过imageWithName或者其他方式直接创建的UIImage,应该都是CGImageRef,这个时候就需要多一步操作

   @property(nullable,nonatomic,readonly)CGImageRef CGImage; // returns underlying CGImageRef or nil if CIImage based...

先取到CGImageRef,然后通过 CIImageimageWithCGImage:这个方法转换一下。完整代码如下

<span style="white-space:pre"></span>- (CIImage *)ciimage {<span style="white-space:pre"></span>    CIImage *returnImage = self.CIImage;<span style="white-space:pre"></span>    if (nil == returnImage) {<span style="white-space:pre"></span>        CGImageRef imageRef = self.CGImage;<span style="white-space:pre"></span>        returnImage = [CIImage imageWithCGImage:imageRef];<span style="white-space:pre"></span>    }<span style="white-space:pre"></span>    return returnImage;<span style="white-space:pre"></span>}

二:CIFilter的创建

CIFilter是的定义中是这样的

/** Creates a new filter of type 'name'. 

 On OSX, all input values will be undefined.

 On iOS, all input values will be set to default values. */

+ (nullableCIFilter *) filterWithName:(NSString *) name;

是以 'name'创建的,那么'name'怎么获取呢?

1)程序中可以这样获取所有的'name';

    <span style="white-space:pre"></span>NSArray *names = [CIFilter filterNamesInCategory:kCICategoryBuiltIn];    <span style="white-space:pre"></span>NSLog(@"all names is %@",names);
2)点击这个链接,可以从苹果官网上面去查找所有的滤镜 苹果官网全部滤镜。

对于一个CIFilter而言,输入参数可以通过其自身属性 attributes 输出查看,定义如下:

/** Returns a dictionary containing key/value pairs describing the filter. (see description of keys below) */

@property (nonatomic,readonly) CI_DICTIONARY(NSString*,id) *attributes;

三:输出后的后续处理。

前面说过,CIFilter是对CIImage进行操作,CIFilter的参数outputImage 就是加入滤镜之后的输出CIImage,这个时候,一般情况下,是要把CIImage转换成UIImage,然后赋值给UIImageView,展示给客户端,so,怎么转换成UIImage呢?

1)UIImage有下面这么两种根据CIImage创建UIImage的类方法和对应的对象方法

#if __has_include(<CoreImage/CoreImage.h>)

+ (UIImage *)imageWithCIImage:(CIImage *)ciImageNS_AVAILABLE_IOS(5_0);

+ (UIImage *)imageWithCIImage:(CIImage *)ciImage scale:(CGFloat)scale orientation:(UIImageOrientation)orientationNS_AVAILABLE_IOS(6_0);

2)将CIImage转换成CGImageRef

    CIContext *content = [CIContext contextWithOptions:nil];    CGImageRef ref = [content createCGImage:self fromRect:self.extent];

PS:注意事项

coreImage容易堵塞线程,尽量的异步操作

滤镜链,滤镜链,是一条链式,所以尽量的重新创建一个CIFilter,而不是一直重复的使用一个CIFiter,即使干的活都一样也不行。


1 0
原创粉丝点击