Swift 3.0中如何为选定区域应用现有CIFilter(ROI实现)
嘿,这个问题我之前也碰到过!其实不用自定义滤镜也能实现——核心思路是用**遮罩(Mask)**来控制滤镜只作用在选定区域,把处理后的区域和原图拼接起来就行。下面给你具体的Swift 3.0实现步骤:
实现方法:用遮罩混合滤镜区域与原图
1. 准备基础素材
先获取原图/视频帧、选定的目标区域,以及你要使用的系统CIFilter:
// 假设你已经拿到了原图的CIImage let originalImage = CIImage(image: UIImage(named: "yourImage")!)! // 自定义选定的目标区域(示例为中心200x200的矩形) let targetRect = CGRect(x: originalImage.extent.midX - 100, y: originalImage.extent.midY - 100, width: 200, height: 200) // 初始化系统滤镜(这里以复古褐色滤镜为例) let sepiaFilter = CIFilter(name: "CISepiaTone")! sepiaFilter.setValue(originalImage, forKey: kCIInputImageKey) sepiaFilter.setValue(0.8, forKey: kCIInputIntensityKey) let filteredImage = sepiaFilter.outputImage!
2. 创建区域遮罩
用CIRectangleGenerator生成一个仅在选定区域为白色(不透明)、其余区域为黑色(透明)的遮罩:
let maskGenerator = CIFilter(name: "CIRectangleGenerator")! maskGenerator.setValue(CIVector(cgRect: targetRect), forKey: kCIInputRectangleKey) maskGenerator.setValue(originalImage.extent.size.width, forKey: kCIInputWidthKey) maskGenerator.setValue(originalImage.extent.size.height, forKey: kCIInputHeightKey) let maskImage = maskGenerator.outputImage!
如果需要圆角区域,换成CIRoundedRectangleGenerator并设置kCIInputRadiusKey参数即可。
3. 混合滤镜图像与原图
用CIBlendWithMask将滤镜处理后的图像和原图混合,遮罩会控制只有选定区域显示滤镜效果:
let blendFilter = CIFilter(name: "CIBlendWithMask")! blendFilter.setValue(filteredImage, forKey: kCIInputImageKey) blendFilter.setValue(originalImage, forKey: kCIInputBackgroundImageKey) blendFilter.setValue(maskImage, forKey: kCIInputMaskImageKey) // 最终结果:仅选定区域应用了滤镜的图像 let finalImage = blendFilter.outputImage!
4. 视频处理的适配逻辑
如果是处理视频帧,只需要把上述逻辑放到视频帧的处理回调中即可。比如配合AVVideoComposition自定义处理块,对每一帧重复执行遮罩混合的步骤,再导出处理后的视频。
额外优化:柔化区域边缘
如果觉得区域边界太生硬,可以给遮罩加高斯模糊实现羽化效果:
let blurFilter = CIFilter(name: "CIGaussianBlur")! blurFilter.setValue(maskImage, forKey: kCIInputImageKey) blurFilter.setValue(5.0, forKey: kCIInputRadiusKey) // 模糊半径越大,边缘越柔和 let softenedMask = blurFilter.outputImage! // 使用柔化后的遮罩进行混合即可
内容的提问来源于stack exchange,提问作者PlusInfosys
相关产品推荐
相关产品推荐

