带金属的核心图像滤镜
我们可以创建在iOS 11或更高版本中以金属阴影语言(MSL)编写的自定义核心图像滤镜。
在A8或更高版本的设备上受支持。
它可以在构建时进行预编译,因此可以获得更好的性能。 现有方法(GLSL或CIKernel语言)在运行时进行编译。
以下是添加到CIKernel
的新API:
公共便利init(functionName名称:字符串,fromMetalLibraryData数据:数据)引发公共便利init(functionName名称:字符串,fromMetalLibraryData数据:数据,outputPixelFormat格式:CIFormat)引发
这是CIColorKernel
的简单MSL实现:
#include
使用命名空间金属;
#include //包含CIKernelMetalLib.h
extern“ C” {名称空间coreimage {
float4 myColor(sample_t s){
返回s.grba;
}
}}
让我们将其另存为kernel.metal
或其他名称(任何名称都可以,但是扩展名应该是.metal
)。
可以使用新的API初始化使用着色器功能的CIColorKernel
:
让url = Bundle.main.url(forResource:“ default”,withExtension:“ metallib”)!
让数据=尝试! 数据(contentsOf:url)
让内核=尝试! CIColorKernel(functionName:“ myColor”,fromMetalLibraryData:data)
因此,可以像这样实现具有自定义内核的CIFilter
子类:
导入CoreImage
MetalFilter类:CIFilter {
专用let内核:CIColorKernel
var inputImage:CIImage?
覆盖init(){
让url = Bundle.main.url(forResource:“ default”,withExtension:“ metallib”)!
让数据=尝试! 数据(contentsOf:url)
内核=试试! CIColorKernel(functionName:“ myColor”,fromMetalLibraryData:data)
super.init()
}
需要初始化吗?(编码器aDecoder:NSCoder){
fatalError(“ init(coder :)尚未实现”)
}
func outputImage()-> CIImage? {
卫队让inputImage = inputImage else {返回零}
返回kernel.apply(范围:inputImage.extent,参数:[inputImage])
}
}
自定义过滤器可以这样使用:
让过滤器= MetalFilter()
filter.inputImage = inputImage
让outputImage = filter.outputImage()
而已!
好的,现在我们可以构建项目了。 让我们在您的设备上运行它!
+ [CIKernel kernelWithFunctionName:fromMetalLibraryData:outputPixelFormat:error:]函数'myColor'不存在。
嗯,但是它说myColor
不存在。 但是它存在…
我在这里找到解决方案:
- kernelWithFunctionName:fromMetalLibraryData:错误:— CIKernel
Apple开发人员文档
我们需要在构建设置中指定一些选项:
- 在“
Other Metal Compiler Flags
选项中指定-fcikernel
标志 - 使用名为
MTLLINKER_FLAGS
的键添加用户定义的设置,该键的值为-cikernel