乐趣区

关于ios:iOS-图像处理技术追踪Core-Image

Core Image 是苹果官网提供的图像处理框架,通过丰盛的 built-in(内置)或自定义 Filter(过滤器)高效解决动态图片、动静图片或视频。开发者还能够通过结构 Filter 链或自定义 Core Image Kernel 来实现更丰盛的成果。
在 WWDC20 中,苹果官网针对 Core Image 技术在以下三方面做了优化:Core Image 对视频 / 动图的反对、基于 Metal 构建 Core Image (CI) Kernel 以及 Core Image 的 Debug 反对。

优化 Core Image 对视频 / 动图的反对

创立 CIContext

创立 CIContext 时,须要遵循一个 view 一个 context 的准则。因为视频的每一帧都会发生变化,将 CIContext 的 cacheIntermediates 属性设置为 false 能够大大减少内存耗费。

如果在应用 Core Image 时将同时使用 Metal(作为输出或输入),通过设置 MTLCommandQueue 属性创立 CIContext 将会是较好抉择。在不应用 MTLCommandQueue 的状况下,每一个 Metal 或 CoreImage 执行的工作都在不同队列中并以 wait 命令分隔开,导致工作执行效率低。通过设置 MTLCommandQueue 创立的 CIContext 和相应的 Metal 工作在同一队列中,能进步 app 的运行效率。

图一:不应用 MTLCommandQueue 的工作流程

图二:应用 MTLCommandQueue 的工作流程

编写 Core Image Kernel(在 Metal 中实现)

为了将成果解决得更丰盛,通过 Metal 来实现自定义 CI Kernel 是个高效的抉择。苹果官网提供了的许多不便部署的内置工具(都通过 Metal 实现),如内置 CI 滤镜。通过 Metal 实现自定义 CI Kernel,不仅 app 的 runtime 编译工夫将会大大减少(这段工作会移至 app 构建实现后进行),开发者还能取得高性能语言个性(如 gather-reads、group-writes、半精度浮点数)、高效开发体验(如缩进查看、缩进高光)等性能。

iOS 开发交换技术群:563513413,不论你是大牛还是小白都欢送入驻,分享 BAT, 阿里面试题、面试教训,探讨技术,大家一起交流学习成长!

抉择适合的 View 类

如果要对视频 / 动图利用特效,动态内容 View 如 UIImageView 或 NSImageView 该当被防止。AVPlayerView 和 MetalKit View(MTKView)是个两个不错的抉择。前者为简略抉择,后者为进阶抉择。

应用 AVPlayerView 时,须要创立 AVMutableVideoComposition 对象,CI 滤镜在 block 中执行图像处理工作。在进行断点 debug 时,通过点击 CIImage 对象地址右侧的眼睛图示能够浏览 CI 滤镜解决流程的详细信息。

官网提供的案例中,Core Image 还将 10 位的 HDR 视频帧数据主动从 HLG 转化成了 Core Image working space。

图三:CI Image 断点测试中展示的解决流程

应用 MTKView 时,开发者须要以 frame 和 device 作为参数重载 init 办法。VIew 对应的 CIContext 也将在 init 函数中被创立。如果咱们在 macOS 中开发反对 HDR 的 view,color-Pixel-Format 属性须要被设定为 rgba16Float,wants-Extended-Dynamic-Range-Content 属性须要被设定为 true。设定完 init 办法后,开发者须要实现 draw-in view 办法。须要留神的是,此处并未间接将 Metal 材质传入 CIRenderDestination 函数,而是创立了一个会返回 texture 的 block。这使得 CIContext 能在后面的帧尚未实现时将 Metal 工作入队。之后该办法会执行渲染工作(至指定目的地)并创立 command buffer 将以后绘制后果渲染至 view。

自己也亲自尝试了通过 Core Image 解决视频的整个流程。以下案例应用 CIVortexDistortion 滤镜对视频进行逐帧解决并渲染,展现内容蕴含外围代码、原视频、CI 滤镜解决后视频以及断点测试的滤镜逐帧解决图示。

复制代码

let filepath: String? = Bundle.main.path(forResource: "test_video", ofType: "MOV")let fileURL 
= URL.init(fileURLWithPath: filepath!)let asset = AVAsset(url: fileURL)let item = AVPlayerItem
(asset: asset)item.videoComposition = AVMutableVideoComposition(asset: asset) { request in    l
et filter = CIFilter(name: "CIVortexDistortion")    filter?.setValue(request.sourceImage, forKey: kCIInputImageKey)    filter?.setValue(NSNumber(400), forKey: "inputAngle")    filter?.setValue(NSNumber(1200), forKey: "inputRadius")    filter?.setValue(CIVector(x: 700, y: 400), forKey: "inputCenter")    let out = filter?.outputImage    request.finish(with: out ?? request.sourceImage, context: nil)}avPlayer = AVPlayer(playerItem: item)
复制代码 

加 CIVortexDistortion 滤镜后的视频

图四:断点调试时 Core Image 对每帧的解决流程

基于 Metal 构建 Core Image Kernel

应用 CI Kernel 有诸多劣势,包含上文提及的缩短 runtime 编译工夫、高性能语言个性(如 gather-reads、group-writes、半精度浮点数)、高效开发体验(如缩进查看、缩进高光)。基于 Metal 构建 CI Kernel 有 5 步流程,会在下文进行逐个介绍。

在我的项目中减少自定义构建规定

苹果官网举荐在我的项目 target 中减少两项自定义构建规定。第一个构建规定针对以“.ci.metal”为后缀名的文件。该构建规定会创立一个以“.ci.air”为后缀名的二进制输入文件。

图五:针对“*.ci.metal”文件的构建规定

第二个构建规定针对以“.ci.air”为后缀名的文件(上一个构建规定的输入后果)。该构建规定会在 app 的资源文件夹内创立以“.ci.metallib”为后缀名的输入文件。

图六:针对“*.ci.air”文件的构建规定

在我的项目中减少.ci.metal 资源

在 Xcode 提供的创立面板中抉择 Metal File 即可。开发者对 Metal File 进行命名时须要以“.ci”作为后缀名,这样我的项目中新生成的文件会以“.ci.metal”作为后缀名。

编写 Metal Kernel

便携 Metal Kernel 须要 include CoreImage.h 头文件,用来应用 Metal 和 Core Image 提供的各种类。官网提供的范例编写了一个 CIColorKernel,输出参数为 coreimage::samle_t 对象(示意输出图片的一个像素)、time 和 coreimage::destination 对象,返回 float4 像素。

图七:苹果官网提供的代码范例:Metal Kernel 编写

苹果官网为开发者提供了形容 CI Kernel 中 Metal Shader 语言的文档,详情见「Metal Shading Language for Core Image Kernels」①。

加载 Kernel 并利用于新图像(基于 Swift)

Kernel 会被 CI 滤镜的子类应用。苹果官网举荐开发者在实例化滤镜的 CIKernel 对象时应用动态属性(static property),这种状况下加载 metallib 资源的工作仅会执行一次(在首次须要时)。CI 滤镜的子类也必须重载输入图片的属性,Kernel 将在 getter 中进行图像处理并创立新图像。

图八:苹果官网提供的代码范例:Kernel 加载与应用

Core Image 的 Debug 反对

苹果官网在 WWDC20 具体介绍了 Debug 个性:CI_PRINT_TREE。

什么是 CI_PRINT_TREE

CI_PRINT_TREE 的根底框架与 Xcode 提供的 Core Image Quick Look 反对雷同。Core Image Quick Look 为开发者提供了快捷可视化的 Core Image 图片(详见上文图三),而 CI_PRINT_TREE 反对几种不同的模式和选项用来查看 Core Image 如何优化和渲染图像。

如何启用 CI_PRINT_TREE

苹果官网提供了 CI_PRINT_TREE 的两种启动形式。最罕用的办法是编辑 Xcode target scheme,在 Arugments 窗体下的环境变量列表中退出 CI_PRINT_TREE 并设置值。另一种办法是在 Terminal.app 中通过命令行启动 CI_PRINT_TREE(须要在执行应用程序前设定)。

图九:启用 CI_PRINT_TREE 的两种形式

如何管制 CI_PRINT_TREE

CI_PRINT_TREE 的字符串格局为“”

  • graph type:示意 Core Image render 的若干 stage,包含 type-1 初始图像(有助于查看被应用的色调空间)、type-2 优化后的图像(有助于查看 core image 对 render 的优化成果)、type-4 级联图像(有助于查看各 stage 如何级联于 GPU 程序,以便理解 render 须要多少两头缓存)以及 type-7(输入图像 type1、2 和 4)。

图十:苹果官网对 graph type 四个 stage 的形容

  • output type:输入格局能够是 pdf 或 png。在 macOS 上 trees 会被存储在长期我的项目文件夹,在 iOS 上 trees 会被存储在文档(Documents)目录下。如果 output type 没有确定,core image 会把 tree 以紧凑文本格式输入在规范输入(stdout)。通过设置 CI_LOG_FILE=“oslog”,文本也能够返回 Console.app(在 iOS 开发中更为不便)。
  • options:对于 CI_PRINT_TREE,开发者能够设定额定的选项。如通过设定 context==name 来限度输入(仅输入名字雷同的 context),或是通过设定 frame-n 来框定具体输入 context 的哪一帧。更多 option 及详情请见图十一。设定 option 对 debug 能提供很大帮忙,但也需谨慎应用,因为生产这些文件须要额定的工夫和内存

图十一:苹果官网提供的 option

图十二:type 设定为 7 时 tmp 文件夹下的文件

如何取得 CI_PRINT_TREE 文件

在 macOS 中,开发者只须要进入“/tmp”文件夹就能找到生成的 CI_PRINT_TREE 文件。须要留神的是沙盒利用会应用特有的长期存储文件夹。

在 iOS 中,开发者须要将 Custom iOS Target Properties 中的“Application supports iTunes file sharing”项设为 YES(图十三)。这样生成的 CI_PRINT_TREE 文件能够在连贯中的 iOS 设施上被找到并拖拽至 macOS 存储中。

图十三:Custom iOS Target Properties 中进行设置

如何解释 CI_PRINT_TREE 文件

读 CI_PRINT_TREE 时,须要遵循以下规定:

  • 输出在底层,输入在顶层
  • 绿色节点代表卷曲内核(warp kernel),红色节点代表色彩内核(color kernel

图十四:绿色节点与红色节点示例

  • 在树的初始地位(initial tree)很容易找到色彩搭配节点(colormatch nodes),外面记录了搭配前后的色调空间名称。苹果官网提供的案例为 ITUR_2100_HLG_to_workingspace,即 HLG 色调空间转化为 Core Image 线性色调空间。

图十五:苹果官网案例中 initial tree 对色调空间的形容

  • 每个节点会显示 Region of Interest(ROI),示意该节点在 render 中被应用的范畴。

如果开发者在 CI_PRINT_TREE 管制字符串中抉择 type-4 并在 option 中设定 dump-intermediates,产生的级联图片会展现两头缓存的每一次 pass(除了 output pass)及其耗时、像素点数量和像素点格局(用来查找耗时大、占内存大的 pass)。这对 render 内追踪谬误十分有帮忙。如果树中没有展现两头图,那么阐明这张图在先前渲染的时候已被缓存,因而 Core Image 没有渲染它的必要。

图十六:设定 dump-intermediates 的 debug 成果展现

Core Image 在手淘图片库中的利用可能

手淘图片库中的 CDN 图片适配解决库(TBCDNImage)的外围目标是为不同终端设备、网络环境下的图片展现提供最优解。目前思考的维度次要是终端设备硬件和网络状态,思考的参数则是图片尺寸、压缩比率、锐化等图片属性。随着苹果在 Core Image、端智能(CoreML)、硬件反对(自研芯片)等方面进行技术晋升,手淘的 CDN 图片适配解决库能够思考减少“图片内容”作为新的维度,减少亮度、对比度、滤镜、图片品种等新参数。以下为局部利用场景:

  • 辨认亮度较暗的图片,晋升亮度做 CDN 图片适配解决
  • 判断图片内容品种(如美食),依据不同内容品种的图片减少适宜的滤镜做 CDN 图片适配解决
  • 依据挪动终端设备屏幕亮度(或深 / 浅色模式)批改图片色调做 CDN 图片适配解决,达到护眼成果

对 Core Image 技术的瞻望

总结全文,WWDC20 对 Core Image 技术的晋升次要在三方面:

  • 优化 CI 对视频 / 动图的反对,包含开发流程简化、逐帧解决性能晋升等。
  • 容许开发者更自在的构建 Core Image Kernel,使 CI 的特效解决更加丰盛
  • 针对 CI 开发流程提供更高效的 Debug 反对

随着苹果将来自研芯片的底层硬件反对将提供视频流晦涩的逐帧解决与渲染。笔者认为 Core Image 技术将会在以下场景有较大利用价值:

  • 直播滤镜 / 特效性能原生化(解脱自研或第三方 API),实现品质更高的实时滤镜渲染
  • 视频拍摄减少滤镜性能(如淘宝或咸鱼的商品视频录制

iOS 图像处理技术追踪 -Core Image

退出移动版