使用带sampler参数的CIColorKernel/CIBlendKernel初始化崩溃问题求助
崩溃原因
你触发崩溃的核心原因是选错了Core Image内核类型:
CIColorKernel的设计定位是逐像素颜色转换,只接受coreimage::sample_t类型的图像输入参数,系统会自动为当前处理的像素点采样对应输入图像的颜色值,不支持在参数中手动声明coreimage::sampler类型,也不允许在内核中手动调用采样、获取图像extent等操作。- 你写的第一个内核使用了
sampler参数,不符合CIColorKernel的函数签名要求,初始化时会返回nil,try!强制解包nil就触发了你遇到的Foundation._GenericObjCError.nilError报错。 - 你后续替换的仅使用
sample_t参数的内核符合CIColorKernel的要求,所以可以正常运行。
解决方法
因为你的转场逻辑需要获取图像范围、手动判断坐标,更适合使用通用的CIKernel类型,修改成本极低:
- 仅需要把Swift代码中内核的类型从
CIColorKernel替换为CIKernel即可,原有Metal代码不需要任何改动:
class CIWipeRenderer: CIFilter { var backgroundImage:CIImage? var foregroundImage:CIImage? var inputTime: Float = 0.0 // 把CIColorKernel改为CIKernel static var kernel:CIKernel = { () -> CIKernel in let url = Bundle.main.url(forResource: "AppCIKernels", withExtension: "ci.metallib")! let data = try! Data(contentsOf: url) return try! CIKernel(functionName: "wipeLinear", fromMetalLibraryData: data) }() override var outputImage: CIImage? { guard let backgroundImage = backgroundImage, let foregroundImage = foregroundImage else { return nil } return CIWipeRenderer.kernel.apply(extent: backgroundImage.extent, arguments: [backgroundImage, foregroundImage, inputTime]) } }
如果你的逻辑不需要手动控制采样和坐标判断,也可以调整内核代码仅使用sample_t参数适配CIColorKernel即可。
内容的提问来源于stack exchange,提问作者Deepak Sharma
相关产品推荐
相关产品推荐

