如何让CIFilter的CIGlassDistortion纹理高度匹配原图?
问题:CIGlassDistortion滤镜输出纹理高度偏小排查
尽管为inputTexture和输入图像使用了同一张CIImage,但最终输出结果中纹理的高度明显偏小。请帮忙排查以下代码是否存在配置遗漏:
var filter: CIFilter? switch style { case "gaussian": filter = CIFilter(name: "CIGaussianBlur") filter?.setValue(radius, forKey: kCIInputRadiusKey) case "motion": filter = CIFilter(name: "CIMotionBlur") filter?.setValue(radius, forKey: kCIInputRadiusKey) case "glass": filter = CIFilter(name: "CIGlassDistortion") filter?.setValue(radius * 100, forKey: kCIInputScaleKey) filter?.setValue(ciImage, forKey: "inputTexture") filter?.setValue(CIVector(x: ciImage.extent.size.width, y: ciImage.extent.size.height), forKey: kCIInputCenterKey) default: return } filter?.setValue(ciImage, forKey: kCIInputImageKey) guard let outputImage = filter?.outputImage else { return }
效果对比图:
问题排查与修复
- 问题根源:
CIGlassDistortion滤镜的inputCenter参数设置错误。你当前传入的是图像右下角坐标(ciImage.extent.size.width和ciImage.extent.size.height),而非图像中心坐标。滤镜会以此错误的中心为基准计算纹理映射,导致纹理被异常缩放偏移,最终出现高度偏小的视觉效果。 - 修复代码:将
inputCenter改为图像的中心坐标,直接使用CIImage.extent的midX和midY属性:
case "glass":
filter = CIFilter(name: "CIGlassDistortion")
filter?.setValue(radius * 100, forKey: kCIInputScaleKey)
filter?.setValue(ciImage, forKey: "inputTexture")
// 修正为图像中心坐标
filter?.setValue(CIVector(x: ciImage.extent.midX, y: ciImage.extent.midY), forKey: kCIInputCenterKey)
- **补充说明**:`midX`和`midY`是系统提供的属性,能直接获取图像extent的中心位置,比手动计算`size.width/2`更可靠——如果图像的extent原点不是(0,0),手动计算会再次出错,而`midX`/`midY`会自动适配extent的实际位置。 内容的提问来源于stack exchange,提问作者edvardgospel
相关产品推荐
相关产品推荐

