CIFilter & Core Image

2019-10-06  本文已影响0人  纯情_小火鸡

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会为你处理细节。

architecture_2x.png

Core Image 提供了如下功能:

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

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

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

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

Core Image 包括:

2. CIFilter

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

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

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

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

2.1 Subclassing Notes

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

2.2 Methods to Override

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

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步:

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

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

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

syntax.png

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

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

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

上一篇 下一篇

猜你喜欢

热点阅读