CIFilter & Core Image

1. Core Image

Core Image是一种图像处理和分析技术,旨在为静止和视频图像提供近乎实时的处理。它使用GPU或CPU呈现路径,对Core Graphics, Core Video, and Image I/O frameworks中的图像数据类型进行操作。Core Image通过提供一个易于使用的应用程序编程接口(API)来隐藏底层图形处理的细节。您不需要了解OpenGL、OpenGL ES或Metal的细节来利用GPU的能力,也不需要了解Grand Central Dispatch (GCD)来获得多核处理的好处。Core Image会为你处理细节。

CIFilter & Core Image_第1张图片
architecture_2x.png

Core Image 提供了如下功能:

  • 获取内建的图像处理filters
  • 特征检测能力
  • 支持自动图像放大
  • 链接多个filter同时作用来产生自定义效果的能力
  • 支持创建自定义的跑在GPU的filter
  • 基于反馈的图像处理能力

Core Image提供了数百个内置过滤器。您可以通过为过滤器的输入参数提供键值对来设置过滤器。一个过滤器的输出可以是另一个过滤器的输入,这使得将多个过滤器链接在一起以创建惊人的效果成为可能。如果您创建了希望再次使用的复合效果,则可以子类CIFilter来捕获效果。

有十多种过滤器。有些是为了达到艺术效果而设计的,比如风格化和半色调滤镜类。其他的是最佳的解决图像问题,如颜色调整和锐化过滤器。

Core Image可以分析图像的质量,并提供一组具有最佳设置的过滤器,用于调整色调、对比度和色调颜色,以及校正诸如红眼之类的flash伪影。它通过一个方法调用完成所有这一切。

Core Image可以在静止图像中检测人脸特征,并在视频图像中随着时间的推移进行跟踪。了解面部的位置可以帮助您确定放置小插图的位置或应用其他特殊过滤器。

Core Image 包括:

  • CIImage 保存图像数据的类,可以通过UIImage,图像文件或者像素数据(CVPixelBuffer)来创建,包括未处理的像素数据。
  • CIFilter 表示应用的滤镜,对图片属性进行细节处理。它用键值设置的方式对所有的像素进行操作。
  • CIContext 表示上下文,如 Core Graphics 以及 Core Data 中的上下文用于处理绘制渲染以及处理托管对象一样,Core Image 的上下文也是实现对图像处理的具体对象。可以从其中取得图片的信息。


2. CIFilter

是一种通过操纵一个或多个输入图像或生成新的图像数据来生成图像的图像处理器。

其获取一个或多个image作为输入源,并产生CIImage作为输出。一些filter也可以根据其他类型的输入参数生成图像,这些参数通过使用键值对设置。

在处理图像、创建过滤器生成器或编写自定义过滤器时,可以将CIFilter对象与其他 Core Image 类(如CIImage、CIContext,CIColor)一起使用,以利用内置的核心图像过滤器。

CIFilter对象是可变的,因此不能在线程之间安全地共享。每个线程可以创建并拥有其自己的CIFilter对象,但是你可以在线程之间传递filter的不可变输入和输出的CIImage对象。

2.1 Subclassing Notes

你可以子类化CIFilter来创建自定义过滤器效果:

  • 链接两个或多个内置核心图像过滤器
  • 使用自己编写的 image-processing kernel

2.2 Methods to Override

无论你的子类是通过链接过滤器还是实现它自己的内核来提供效果,你都应该:

  • 将任何输入参数声明为属性,其名称前缀为input,例如inputImage。

  • 重写setDefaults()方法,为已声明的任何输入参数提供默认值。

  • 实现一个outputImage方法来创建一个具有过滤器效果的新CIImage。

CIFilter类在归档、复制和释放过滤器时会自动管理输入参数。因此你的子类必须遵守以下准则,以确保正确的行为:

将输入参数存储在名称前缀为input的实例变量中。

不要使用自动合成的实例变量,因为它们的名称会自动地以下划线作为前缀。相反,手动合成属性。例如:

@ synthesize inputMyParameter;

如果使用手动引用计数,不要在dealloc方法实现中释放输入参数实例变量。CIFilter类中的dealloc实现使用键值编码自动将所有输入参数的值设置为nil。

//如下使用了一个sepia深褐色效果的内建滤镜,假设资源图片名为image,可以分为4步:
  // 1 获取资源的url
  let fileUrl = Bundle.main.url(forResource: "image", withExtension: "png")
  if let fileURL = fileUrl {
      // 2 根据url生成CIImage
      let beginImage = CIImage(contentsOf: fileURL)
      // 3 创建CIFilter并以key-value形式设置效果的属性
      let filter = CIFilter(name: "CISepiaTone")
      filter?.setValue(beginImage, forKey: kCIInputImageKey)
      filter?.setValue(0.5, forKey: kCIInputIntensityKey)
      // 4 得到filter.outputImage,创建UIImage对象
      if let outputImage = filter?.outputImage {
          let newImage = UIImage(ciImage: outputImage)
          imageView.image = newImage
      }
  }
//如果在多次调用的情况下,可考虑将第4步进行优化。即缓存CIContext,然后从context创建CIImage
let context = CIContext(options: nil)
let cgimg = context.createCGImage(outputImage, from: filter?.outputImage?.extent ?? CGRect.zero)
let newImage = UIImage(cgImage: cgimg!)
imageView.image = newImage
  //可使用该方法获取所有系统滤镜,该方法会返回一个内建filter名字的数组
  let properties = CIFilter.filterNames(inCategory: kCICategoryBuiltIn)
  print(properties)

  for filterName in properties {
      let filter = CIFilter(name: filterName)
      //会返回一个描述该filter信息的字典
      print(filter?.attributes)
  }


3. 自定义Filter

自定义一个filter可以分为3步:

  • 编写 CIKernel:使用 CIKL语言自定义滤镜效果。
  • 加载 CIKernel:CIFilter 读取编写好的 CIKernel文件。
  • 设置参数:设置 CIKernel 需要的输入参数以及 DOD 和 ROI。

说明:CIKL全称是Core Image Kernel Language,为编写CIKernel的语言,语法几乎和C语言一样, 是 OpenGL Shading Language (GLSL) 的子集;CIKernel为filter对应的执行脚本;DOD为domain of definition,即filter处理后输入的图片区域,ROI(region of interest)当前处理区域。

kernel的入参只支持如下几种:

  • sampler:可以理解成纹理,或者图片。外部以 CIImage 形式传入。
  • __table sampler:表示颜色查找表(lookup table),虽然它也是图片,但是添加该声明可以避免被修改。外部以 CIImage 形式传入。
  • __color:表示颜色。外部以 CIColor 形式传入。
  • float:kernel 内部处理都是 float 类型。外部以 NSNumber 形式传入。
  • vecN:表示一个多元向量。比如 vec2 可以表示一个点,vec4 可以表示一个色值。外部以 CIVector 形式传入。

kernel 中包含很多内建函数,下图列出了一些常用的方法说明:

CIFilter & Core Image_第2张图片
syntax.png

了解更多,可以参考 Core Image Kernel Language Reference, OpenGL ES Shading Language Reference。

Core Image 内置了3种适用于不同场景的 Kernel,可以根据实际需求来选择。

  • CIColorKernel:用于处理色值变化的 Filter。
  • CIWarpKernel:用于处理形变的 Filter。
  • CIKernel:通用。

也使用 Quartz Composer 来做 Core Image 滤镜图表的原型。

你可能感兴趣的:(CIFilter & Core Image)