19675125c6fa2ae2d6dc82a78b991537
Core Image【1】—— 概述

Core Image 系列,目前的文章如下:

  • Core Image【1】—— 概述
  • Core Image【2】—— 自定义 Filter
  • Core Image【3】—— 2017 新特性
  • Core Image【4】—— 2018 新特性

PS:

如果想了解 Core Image 相关,建议按序阅读,前后有依赖。


前言

本文将会介绍逐一介绍 Core Image 相关基础概念、使用方式、注意点以及和其他图像处理方案的对比。

现在,开始吧~

Core Image 概述

Core Image 是 iOS5 新加入到 iOS 平台的一个图像处理框架,提供了强大高效的图像处理功能, 用来对基于像素的图像进行操作与分析, 内置了很多强大的滤镜(Filter) (目前数量超过了180种), 这些Filter 提供了各种各样的效果, 并且还可以通过 滤镜链 将各种效果的 Filter叠加 起来形成强大的自定义效果。

一个 滤镜 是一个对象,有很多输入和输出,并执行一些变换。例如,模糊滤镜可能需要输入图像和一个模糊半径来产生适当的模糊后的输出图像。

一个 滤镜链 是一个链接在一起的滤镜网络,使得一个滤镜的输出可以是另一个滤镜的输入。以这种方式,可以实现精心制作的效果。

iOS8 之后更是支持自定义 CIFilter,可以定制满足业务需求的复杂效果。

Core Image is an image processing and analysis technology designed to provide near real-time processing for still and video images. It operates on image data types from the Core Graphics, Core Video, and Image I/O frameworks, using either a GPU or CPU rendering path. Core Image hides the details of low-level graphics processing by providing an easy-to-use application programming interface (API). You don’t need to know the details of OpenGL or OpenGL ES to leverage the power of the GPU, nor do you need to know anything about Grand Central Dispatch (GCD) to get the benefit of multicore processing. Core Image handles the details for you.

这是苹果官方文档对于 Core Image 的介绍,大致意思是:Core Image 是一种为静态图像和 Video 提供处理和分析的技术,它可以使用 GPU/CPU 的方式对图像进行处理。Core Image 提供了简洁的 API 给用户,隐藏了图像处理中复杂的底层内容。你可以在不了解 OpenGL、OpenGL ES 甚至是 GCD 的基础上对其进行使用,他已经帮你对这些复杂的内容进行处理了。

废话这么多,苹果就想告诉我们一件事:所有的底层细节他都帮你做好了,你只需要放心调用API就行了。

这就是 Core Image 的基础概念,比较简短,正如它的使用方式一样简洁。

然而在我个人学习过程中,我有一种强烈的感觉:Apple 很重视 Core Image,Core Image 一定会越来越棒。

  • 每年的 WWDC Session 中,都有提及 Core Image 的相关优化。
  • 从最初的几十种内置滤镜到如今的180多种。
  • 从最初只支持 macOS,到如今也支持 iOS。
  • iOS8 之后支持自定义 Filter。
  • iOS8 增强 GPU 渲染,在后台也能继续使用 GPU 进行处理。
  • 引入 CIDetector,提供一些常用的图片识别功能。包括人脸识别、条形码识别、文本识别等。
  • 与越来越多的框架相结合:OpenGLES,PhotoExtension,SceneKit,SpriteKit,Metal。
  • iOS 10之后,支持对原生 RAW 格式图片的处理。
  • ...

So,它真的值得学习!

使用方式

这里我们从它的基础 API 介绍起。

Core Image 的 API 主要就是三类:

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

至于使用,相当的方便。

下面以 “动态模糊” 举例,我们使用系统提供的 CIMotionBlur 来实现。

// 传入滤镜名称(e.g. @"CIMotionBlur"), 输出处理后的图片
- (UIImage *)outputImageWithFilterName:(NSString *)filterName {
    // 1. 将UIImage转换成CIImage
    CIImage *ciImage = [[CIImage alloc] initWithImage:self.imageView.image];

    // 2. 创建滤镜
    self.filter = [CIFilter filterWithName:filterName keysAndValues:kCIInputImageKey, ciImage, nil];
    // 设置相关参数
    [self.filter setValue:@(10.f) forKey:@"inputRadius"];

    // 3. 渲染并输出CIImage
    CIImage *outputImage = [self.filter outputImage];

    // 4. 获取绘制上下文
    self.context = [CIContext contextWithOptions:nil];

    // 5. 创建输出CGImage
    CGImageRef cgImage = [self.context createCGImage:outputImage fromRect:[outputImage extent]];
    UIImage *image = [UIImage imageWithCGImage:cgImage];
    // 6. 释放CGImage
    CGImageRelease(cgImage);

    return image;
}

效果如下:

至于滤镜链,则是和普通滤镜的使用没什么差别。只要把前一个滤镜的输出,当作后一个滤镜的输入,即可实现,就不累述了。

另外,如果想查阅 Filter 的属性,可以通过 attributes 属性来获取。比如这个例子中的 CIMotionBlur<