将核心图像过滤器 (CIBumpDistortion) 仅应用于图像的一部分 + 更改选择半径和 CIFilter 的强度

Apply Core Image Filter (CIBumpDistortion) to only one part of an image + change radius of selection and intensity of CIFilter

我想复制此处显示的一些功能:

所以我希望用户对图像应用 CIBumpDistortion 滤镜并让他选择

1) 通过让他触摸图像上的相应位置,他可以准确地应用它

2a) 圆选择的大小(上图中的第一个滑块)

2b) CIBumpDistortion 过滤器的强度(上图中的第二个滑块)

我阅读了一些以前提出的问题,但它们并没有真正帮助,而且一些解决方案听起来非常不友好(例如,裁剪需要的部分,然后将其重新应用到旧图像)。希望我不要一次要求太多。 Objective-C 将是首选,但任何 help/hint 都会非常感激!提前致谢!

我编写了一个演示 (iPad) 项目,可让您应用大多数受支持的 CIFilters。它会询问每个过滤器所需的参数,并内置对浮点值以及点和颜色的支持。对于凹凸失真过滤器,它允许您 select 一个中心点、一个半径和一个输入比例。

该项目名为 CIFilterTest。您可以从 Github 下载项目 link:https://github.com/DuncanMC/CIFilterTest

应用程序中有相当多的内务管理来支持使用任何支持的过滤器的通用功能,但它应该为您提供足够的信息来实现您自己的凹凸过滤器,正如您所要求的那样。

我想出的应用滤镜并使其在不超出原始图像边界的情况下进行渲染的方法是首先对设置为身份的图像 (CIAffineClamp) 应用钳位滤镜转换,获取该过滤器的输出并将其馈送到 "target" 过滤器(在本例中为凹凸失真过滤器)的输入,然后获取其输出并将其馈送到裁剪过滤器(CICrop) 并将裁剪过滤器的边界设置为原始图像大小。

在示例项目中查找的方法调用showImage,在ViewController.m

您写道:

1) where exactly he wants to apply it by letting him just touch the respective location on the image

2a) the size of the circle selection (first slider in the image above)

2b) the intensity of the CIBumpDistortion Filter (second slider in the image above)

嗯,CIBumpDistortion 具有这些属性:

  • inputCenter是效果的中心
  • inputRadius是圈选的大小
  • inputScale是强度

西蒙

显示隆起:
您必须通过半径大小(在您的情况下为白色圆圈)的图像上的位置(kCIInputCenterKey)

func appleBumpDistort(toImage currentImage: UIImage, radius : Float, intensity: Float) -> UIImage? {
    var context: CIContext = CIContext()
    let currentFilter = CIFilter(name: "CIBumpDistortion")    
    let beginImage = CIImage(image: currentImage)
    currentFilter.setValue(beginImage, forKey: kCIInputImageKey)


    currentFilter.setValue(radius, forKey: kCIInputRadiusKey)
    currentFilter.setValue(intensity, forKey: kCIInputScaleKey)
    currentFilter.setValue(CIVector(x: currentImage.size.width / 2, y: currentImage.size.height / 2), forKey: kCIInputCenterKey)

    guard let image = currentFilter.outputImage else { return nil }

    if let cgimg = context.createCGImage(image, from: image.extent) {
        let processedImage = UIImage(cgImage: cgimg)
        return processedImage
    }
    return nil
}