仅将 CIGaussianBlur 应用于图像的一小部分

Apply CIGaussianBlur only to a small part of an image

我只需要在图像的一小部分应用 CIGaussianBlur 滤镜,如下所示:

有什么办法吗?例如,当我应用过滤器时,我可能认为我必须指定过滤器的维度(例如 CGRectMake)。

var imageToBlur = CIImage(image: coro.logo)
var blurfilter = CIFilter(name: "CIGaussianBlur")
blurfilter.setValue(imageToBlur, forKey: "inputImage")
blurfilter.setValue(2, forKey: "inputRadius")
var resultImage = blurfilter.valueForKey("outputImage") as! CIImage
var blurredImage = UIImage(CIImage: resultImage)
self.immagineCoro.image = blurredImage

尝试使用这个

func blurImage(image:UIImage, forRect rect: CGRect) -> UIImage?
    {
        let context = CIContext(options: nil)
        let inputImage = CIImage(CGImage: image.CGImage!)


        let filter = CIFilter(name: "CIGaussianBlur")
        filter?.setValue(inputImage, forKey: kCIInputImageKey)
        filter?.setValue((70.0), forKey: kCIInputRadiusKey)
        let outputImage = filter?.outputImage

        var cgImage:CGImageRef?

        if let asd = outputImage
        {
            cgImage = context.createCGImage(asd, fromRect: rect)
        }

        if let cgImageA = cgImage
        {
            return UIImage(CGImage: cgImageA)
        }

        return nil
    }

想法是从源图像中的一个矩形制作一个新图像,模糊这个新图像然后将它合成回源图像。

我正在将其作为 UIImage 的扩展以方便使用。

extension UIImage {

    func getImageFromRect(rect: CGRect) -> UIImage? {
        if let cg = self.CGImage,
            let mySubimage = CGImageCreateWithImageInRect(cg, rect) {
                return UIImage(CGImage: mySubimage)
        }
        return nil
    }

    func blurImage(withRadius radius: Double) -> UIImage? {
        let inputImage = UIKit.CIImage(CGImage: self.CGImage!)
        if let filter = CIFilter(name: "CIGaussianBlur") {
            filter.setValue(inputImage, forKey: kCIInputImageKey)
            filter.setValue((radius), forKey: kCIInputRadiusKey)
            if let blurred = filter.outputImage {
                return UIImage(CIImage: blurred)
            }
        }
        return nil
    }

    func drawImageInRect(inputImage: UIImage, inRect imageRect: CGRect) -> UIImage {
        UIGraphicsBeginImageContext(self.size)
        self.drawInRect(CGRectMake(0.0, 0.0, self.size.width, self.size.height))
        inputImage.drawInRect(imageRect)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage
    }

    func applyBlurInRect(rect: CGRect, withRadius radius: Double) -> UIImage? {
        if let subImage = self.getImageFromRect(rect),
            let blurredZone = subImage.blurImage(withRadius: radius) {
                return self.drawImageInRect(blurredZone, inRect: rect)
        }
        return nil
    }

}

用法:

// your image
let sourceImage = UIImage(...)

// the rect to blur
let targetZone = CGRectMake(-50, sourceImage.size.height - 220, sourceImage.size.width + 100, 220)

// apply our functions to the source image
if let resultImage = sourceImage.applyBlurInRect(targetZone, withRadius: 6.0) {
    // use resultImage
}

之前:

之后:

Swift: 这似乎是一个简单的过程。

// convert UIImage to CIImage
guard let ciImage = imgage.ciImage ?? image.cgImage.map({CIImage(cgImage: [=10=])}) else {
   return
}


// crop out image that needs to be blurred
// be careful about bounds
let imagePartToBlur = ciImage.cropped(to: bounds)

// apply gaussian blur
let filter = CIFilter(name: "CIGaussianBlur")
filter?.setValue(faceImage, forKey: kCIInputImageKey)
filter?.setValue(32, forKey: kCIInputRadiusKey)
let outputImage = filter?.outputImage

// composite the blurred croppedout image to original image and get new image
if let newImageWithBlurredPart = outputImage?.composited(over: ciImage) {
    // now get uimage which is ready to use
    let cgImage = context.createCGImage(newImageWithBlurredPart, from: ciImage.extent)
    let image = UIImage(cgImage: cgImage)
}

Swift 5+

的编辑版本
func blurImage(image: UIImage, forRect rect: CGRect) -> UIImage? {
    let context = CIContext(options: nil)
    let inputImage = CIImage(cgImage: image.cgImage!)
    
    let filter = CIFilter(name: "CIGaussianBlur")
    filter?.setValue(inputImage, forKey: kCIInputImageKey)
    filter?.setValue((70.0), forKey: kCIInputRadiusKey)
    
    guard let outputImage = filter?.outputImage,
          let cgImage = context.createCGImage(outputImage, from: rect)
    else {
        return nil
    }
    
    return UIImage(cgImage: cgImage)
}