带有 CIFilters 的 CAShapeLayer
CAShapeLayer with CIFilters
我想将 CIFilter 应用于 CAShapeLayer.filters。
这个假设是否正确 如何做到这一点:
- 创建 CAShapeLayer
- 从 CAShapeLayer 创建 CGImage 或 UIImage
- 使用 CGImage 或 UIImage 创建 CIFilter
- 将 CIFilter 添加到 CAShapeLayer.filters
为了从 CAShapeLayer 创建 CGImage,我使用了 CAShapeLayer.contents,但在我的例子中,contents 为零,如果我将 CAShapeLayer 渲染到图像上下文,我也无法获取图像.
override func layoutSubviews()
{
if(self.shapeLayer == nil && self.path != nil && self.pathOriginationSize != CGSizeZero)
{
let scaleFactor = self.scaleFactor(self.pathOriginationSize, targetSize: self.bounds.size)
_scaledPath = UIBezierPath(CGPath: self.path.CGPath)
_scaledPath.lineWidth = self.path.lineWidth
_scaledPath.applyTransform(CGAffineTransformMakeScale(scaleFactor.x, scaleFactor.y))
_scaledPath.lineCapStyle = CGLineCap.Round
self.shapeLayer = CAShapeLayer()
self.shapeLayer.path = _scaledPath.CGPath
self.shapeLayer.strokeColor = UIColor.blackColor().CGColor
self.shapeLayer.lineWidth = self.path.lineWidth
let imageSize = CGPathGetBoundingBox(_scaledPath.CGPath).size
UIGraphicsBeginImageContextWithOptions(imageSize, false, UIScreen.mainScreen().scale)
let context = UIGraphicsGetCurrentContext()
self.shapeLayer.renderInContext(context!)
_ = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let cgImage = self.shapeLayer.contents as! CGImageRef
let inputImage = CIImage(CGImage: cgImage)
let blurFilter = CIFilter(name: "CIZoomBlur")
blurFilter?.setValue(inputImage, forKey: kCIInputImageKey)
blurFilter?.setDefaults()
self.shapeLayer.filters = [blurFilter!]
self.shapeLayer.shouldRasterize = true
self.layer.addSublayer(self.shapeLayer)
}
}
CALayer.filters
未在 iOS 上实现。
在这种情况下不需要使用 CAShapeLayer
(因为您不能使用 filters
)。您可以从 UIBezierPath
创建一个 CGImage
(正如您所做的那样;只是 stroke
and/or fill
路径而不是调用 renderInContext
).然后对结果使用 apply
CIFilter
,创建一个 CGImage
并将其分配给 contents
。 (从你上面的代码来看,你似乎明白如何做所有这些事情,所以我就不在这里写了。)
我想将 CIFilter 应用于 CAShapeLayer.filters。 这个假设是否正确 如何做到这一点:
- 创建 CAShapeLayer
- 从 CAShapeLayer 创建 CGImage 或 UIImage
- 使用 CGImage 或 UIImage 创建 CIFilter
- 将 CIFilter 添加到 CAShapeLayer.filters
为了从 CAShapeLayer 创建 CGImage,我使用了 CAShapeLayer.contents,但在我的例子中,contents 为零,如果我将 CAShapeLayer 渲染到图像上下文,我也无法获取图像.
override func layoutSubviews()
{
if(self.shapeLayer == nil && self.path != nil && self.pathOriginationSize != CGSizeZero)
{
let scaleFactor = self.scaleFactor(self.pathOriginationSize, targetSize: self.bounds.size)
_scaledPath = UIBezierPath(CGPath: self.path.CGPath)
_scaledPath.lineWidth = self.path.lineWidth
_scaledPath.applyTransform(CGAffineTransformMakeScale(scaleFactor.x, scaleFactor.y))
_scaledPath.lineCapStyle = CGLineCap.Round
self.shapeLayer = CAShapeLayer()
self.shapeLayer.path = _scaledPath.CGPath
self.shapeLayer.strokeColor = UIColor.blackColor().CGColor
self.shapeLayer.lineWidth = self.path.lineWidth
let imageSize = CGPathGetBoundingBox(_scaledPath.CGPath).size
UIGraphicsBeginImageContextWithOptions(imageSize, false, UIScreen.mainScreen().scale)
let context = UIGraphicsGetCurrentContext()
self.shapeLayer.renderInContext(context!)
_ = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let cgImage = self.shapeLayer.contents as! CGImageRef
let inputImage = CIImage(CGImage: cgImage)
let blurFilter = CIFilter(name: "CIZoomBlur")
blurFilter?.setValue(inputImage, forKey: kCIInputImageKey)
blurFilter?.setDefaults()
self.shapeLayer.filters = [blurFilter!]
self.shapeLayer.shouldRasterize = true
self.layer.addSublayer(self.shapeLayer)
}
}
CALayer.filters
未在 iOS 上实现。
在这种情况下不需要使用 CAShapeLayer
(因为您不能使用 filters
)。您可以从 UIBezierPath
创建一个 CGImage
(正如您所做的那样;只是 stroke
and/or fill
路径而不是调用 renderInContext
).然后对结果使用 apply
CIFilter
,创建一个 CGImage
并将其分配给 contents
。 (从你上面的代码来看,你似乎明白如何做所有这些事情,所以我就不在这里写了。)