在UI元素上应用CIFilters

时间:2016-07-11 17:24:52

标签: swift calayer core-image

我想在UI元素上应用CIFilter。我试图通过.filters成员将它应用到视图层。然而,过滤器不会被应用。

1 个答案:

答案 0 :(得分:1)

以下是一种方法:使用UIGraphicsGetImageFromCurrentImageContext生成UIImage,将过滤器应用于该过滤器,并将包含过滤后图像的图像视图覆盖在原始组件上。

这是一种模糊(taken from my blog):

的方法

获得UIView的模糊表示非常简单:我需要开始一个图像上下文,使用视图层的renderInContext方法渲染到上下文中,然后从上下文中获取UIImage:

UIGraphicsBeginImageContextWithOptions(CGSize(width: frame.width, height: frame.height), false, 1)

layer.renderInContext(UIGraphicsGetCurrentContext()!)

let image = UIGraphicsGetImageFromCurrentImageContext()


UIGraphicsEndImageContext();

一旦我填充了图像,它就是一个相当标准的工作流程,可以应用高斯模糊:

guard let blur = CIFilter(name: "CIGaussianBlur") else
{
    return
}

blur.setValue(CIImage(image: image), forKey: kCIInputImageKey)
blur.setValue(blurRadius, forKey: kCIInputRadiusKey)

let ciContext  = CIContext(options: nil)

let result = blur.valueForKey(kCIOutputImageKey) as! CIImage!

let boundingRect = CGRect(x: -blurRadius * 4,
    y: -blurRadius * 4,
    width: frame.width + (blurRadius * 8),
    height: frame.height + (blurRadius * 8))

let cgImage = ciContext.createCGImage(result, fromRect: boundingRect)


let filteredImage = UIImage(CGImage: cgImage)

模糊图像会比输入图像大,所以我需要明确createCGImage中所需的尺寸。

下一步是在我的视图中添加UIImageView并隐藏所有其他视图。我已将UIImageView隐藏到BlurOverlay,因此在删除它时,我可以确定我没有删除现有的UIImageView

let blurOverlay = BlurOverlay()
blurOverlay.frame = boundingRect

blurOverlay.image = filteredImage

subviews.forEach{ $0.hidden = true }


addSubview(blurOverlay)

说到去模糊,我想确保最后一个子视图是BlurOverlay移除它之一并取消隐藏现有视图:

func unBlur()
{
    if let blurOverlay = subviews.last as? BlurOverlay
    {
        blurOverlay.removeFromSuperview()

        subviews.forEach{ $0.hidden = false }
    }

}

最后,要了解UIView目前是否模糊,我只需要查看其最后一个子视图是否为BlurOverlay

var isBlurred: Bool
{
    return subviews.last is BlurOverlay
}