简介

Core Image是苹果官网提供的图像处理框架,通过丰盛的built-in(内置)或自定义Filter(过滤器)高效解决动态图片、动静图片或视频。开发者还能够通过结构Filter链或自定义Core Image Kernel来实现更丰盛的成果。

在WWDC20中,苹果官网针对Core Image技术在以下三方面做了优化:Core Image对视频/动图的反对、基于Metal构建Core Image (CI) Kernel以及Core Image的Debug反对。这三方面会在下文逐个提到,文末笔者也会浅谈Core Image在手淘图片库中的利用可能以及对Core Image技术的瞻望。

( WWDC 2020精彩内容思否专栏:https://segmentfault.com/blog...  

本篇内容来自于阿里巴巴淘系技术部,无线开发工程师越伯。
更多精彩内容可关注【淘系技术】公众号。)

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

1. 创立CIContext

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

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

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

图二、应用MTLCommandQueue的工作流程

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

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

3. 抉择适合的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滤镜解决后视频以及断点测试的滤镜逐帧解决图示。

代码一、测试外围代码

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

基于Metal构建Core Image Kernel

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

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

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

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

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

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

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

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

3. 编写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」。

4. 加载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> <output type> <options>”

  1. 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的形容

  1. output type:输入格局能够是pdf或png。在macOS上trees会被存储在长期我的项目文件夹,在iOS上trees会被存储在文档(Documents)目录下。如果output type没有确定,core image会把tree以紧凑文本格式输入在规范输入(stdout)。通过设置CI_LOG_FILE="oslog",文本也能够返回Console.app(在iOS开发中更为不便)。
  2. 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),实现品质更高的实时滤镜渲染
  • 视频拍摄减少滤镜性能(如淘宝或咸鱼的商品视频录制)

参考:

① https://developer.apple.com/m...

② https://github.com/duzhaoquan...

团队招人

手淘客户端团队正在进行社招招聘,岗位有iOS Android客户端开发工程师、欢送大家退出咱们。

简历投递:junzhan.yzw@taobao.com

更多无关手淘的技术内容分享敬请关注VX公众号【淘系技术】