Применить CIGaussianBlur только к небольшой части изображения

Мне нужно применить фильтр CGaussianBlur только к небольшой части изображения, например:

введите описание изображения здесь

Есть какой-либо способ сделать это? Например, когда я применяю фильтр, возможно, я думаю, что мне нужно указать размер фильтра (кто-то вроде 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

person Fabio Cenni    schedule 26.08.2015    source источник
comment
разве CIFilter не имеет свойства прямоугольника экстентов?   -  person nielsbot    schedule 25.10.2015


Ответы (4)


Попробуйте использовать это

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
    }
person Che    schedule 25.10.2015
comment
Можете ли вы опубликовать объективный вариант того же самого? - person nr5; 13.11.2015
comment
@Нил - (UIImage*)getBluredImageFromImage:(UIImage*)image forRect:(CGRect)rect { CIContext* context = [CIContext contextWithOptions:nil]; CIImage* inputImage = [CIImage imageWithCGImage:image.CGImage]; CIFilter* filter = [CIFilter filterWithName:@"CIGaussianBlur"]; [filter setValue:inputImage forKey:kCIInputImageKey]; [filter setValue:@(70) forKey:kCIInputRadiusKey]; CIImage* outputImage = [filter outputImage]; - person Che; 26.11.2015
comment
CGImageRef cgImage; if (outputImage) cgImage = [context createCGImage:outputImage fromRect:rect]; if (cgImage) return [UIImage imageWithCGImage:cgImage]; return nil; } Попробуйте скопировать/вставить его в xCode… Так будет лучше :) - person Che; 26.11.2015

Идея состоит в том, чтобы создать новое изображение из прямоугольника в исходном изображении, размыть это новое изображение, а затем скомпоновать его обратно в источник.

Я делаю это расширением 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
}

До:

введите описание изображения здесь

После:

введите описание изображения здесь

person Eric Aya    schedule 25.10.2015

Swift: кажется, что это простой процесс.

// convert UIImage to CIImage
guard let ciImage = imgage.ciImage ?? image.cgImage.map({CIImage(cgImage: $0)}) 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)
}
person Bibek    schedule 17.07.2020

отредактированная версия для 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)
}
person asilturk    schedule 26.08.2020