在 UI 个元素上应用 CIFilter
Apply CIFilters on UI elements
我想在 UI 元素上应用 CIFilter。我试图通过 .filters 成员将它应用到视图层。但是不会应用过滤器。
这是一种方法:使用 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{ [=12=].hidden = true }
addSubview(blurOverlay)
关于去模糊,我想确保最后一个子视图是我的 BlurOverlay
删除它并取消隐藏现有视图:
func unBlur()
{
if let blurOverlay = subviews.last as? BlurOverlay
{
blurOverlay.removeFromSuperview()
subviews.forEach{ [=13=].hidden = false }
}
}
最后,要查看UIView
当前是否模糊,我只需要查看其最后一个子视图是否为BlurOverlay
:
var isBlurred: Bool
{
return subviews.last is BlurOverlay
}
我想在 UI 元素上应用 CIFilter。我试图通过 .filters 成员将它应用到视图层。但是不会应用过滤器。
这是一种方法:使用 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{ [=12=].hidden = true }
addSubview(blurOverlay)
关于去模糊,我想确保最后一个子视图是我的 BlurOverlay
删除它并取消隐藏现有视图:
func unBlur()
{
if let blurOverlay = subviews.last as? BlurOverlay
{
blurOverlay.removeFromSuperview()
subviews.forEach{ [=13=].hidden = false }
}
}
最后,要查看UIView
当前是否模糊,我只需要查看其最后一个子视图是否为BlurOverlay
:
var isBlurred: Bool
{
return subviews.last is BlurOverlay
}