Swift控制台报错:CIKernel's ROI function did not allow tiling,平移CIImage渲染失败
解决CIImage平移时“CIKernel's ROI function did not allow tiling”错误的方案
我之前也踩过iOS 10的这个坑!每次平移CIImage就弹出像素渲染失败的错误,图像直接变灰,确实闹心。给你几个亲测有效的解决思路:
优先用系统自带的CIAffineTransform滤镜
系统滤镜已经帮我们处理好了ROI(Region of Interest)的逻辑,完全不会触发这个tiling错误。代码示例很简单:// 构造平移变换矩阵 let translateTransform = CGAffineTransform(translationX: 你的X偏移量, y: 你的Y偏移量) // 应用到CIImage上 let translatedImage = originalCIImage.applyingFilter("CIAffineTransform", parameters: [ kCIInputTransformKey: translateTransform ])这是最省心的方案,除非你必须用自定义CIKernel,否则优先选这个。
自定义CIKernel时修正ROI回调函数
如果你是自己写的CIKernel做平移,那问题肯定出在ROI回调的计算上。iOS 10对ROI的校验特别严格,必须明确告诉系统:输出图像的某块区域,需要从输入图像的哪块区域采样。
比如你的平移量是(dx, dy),那输出区域rect对应的输入ROI应该是rect反向平移(-dx, -dy),示例代码如下:// 自定义平移Kernel,带ROI回调 let translateKernel = CIKernel(source: """ kernel vec4 customTranslate(sampler src, float dx, float dy) { // 采样平移后的坐标 return sample(src, samplerCoord(src) + vec2(dx, dy)); } """, roiCallback: { (index, outputRect) in // 这里返回输入图像需要的区域:输出区域反向平移 let dx = 你的X偏移量 let dy = 你的Y偏移量 return CGRect( x: outputRect.origin.x - dx, y: outputRect.origin.y - dy, width: outputRect.width, height: outputRect.height ) })只要ROI回调返回的区域准确覆盖了需要采样的像素,错误就会消失。
兜底方案:转成CGImage后再处理
如果上面两种方法都不适用(比如复杂场景下的平移),可以先把CIImage渲染成CGImage,用Core Graphics完成平移后再转回CIImage。示例代码:// 创建CIContext let context = CIContext(options: [CIContextOption.useSoftwareRenderer: false]) guard let originalCGImage = context.createCGImage(originalCIImage, from: originalCIImage.extent) else { // 处理转换失败的情况 return nil } // 用Core Graphics做平移 UIGraphicsBeginImageContextWithOptions(originalCGImage.size, false, originalCGImage.scale) guard let drawContext = UIGraphicsGetCurrentContext() else { UIGraphicsEndImageContext() return nil } drawContext.translateBy(x: 你的X偏移量, y: 你的Y偏移量) drawContext.draw(originalCGImage, in: CGRect(origin: .zero, size: originalCGImage.size)) guard let translatedCGImage = UIGraphicsGetImageFromCurrentImageContext()?.cgImage else { UIGraphicsEndImageContext() return nil } UIGraphicsEndImageContext() // 转回CIImage let translatedImage = CIImage(cgImage: translatedCGImage)这个方法的缺点是会丢失CIImage的矢量渲染特性,适合小尺寸图像或者性能要求不高的场景。
内容的提问来源于stack exchange,提问作者Chewie The Chorkie
相关产品推荐
相关产品推荐

