我正在尝试使用UIGraphicsImageRenderer
和CGBlendModes
将两个CALayer交点绘制到UIImage上,但没有成功。我尝试了所有具有不同图层位置的混合模式,但我几乎卡住了。
这是执行此操作的好方法还是其他方法?
我想实现的目标
这是游乐场代码示例
import UIKit
import PlaygroundSupport
func getDesignElementLayer(byElementID elementID : Int) -> CAShapeLayer
{
let caShapeLayer = CAShapeLayer()
caShapeLayer.frame = CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0)
caShapeLayer.fillColor = UIColor.black.cgColor
switch elementID
{
case 1:
let ovalPath = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 100, height: 100))
caShapeLayer.path = ovalPath.cgPath
case 2:
let bezierPath = UIBezierPath()
bezierPath.move(to: (CGPoint(x: 50, y: 0)))
bezierPath.addLine(to: (CGPoint(x: 0, y: 100)))
bezierPath.addLine(to: (CGPoint(x: 100, y: 100)))
bezierPath.addLine(to: (CGPoint(x: 50, y: 0)))
bezierPath.close()
caShapeLayer.path = bezierPath.cgPath
default:
print("")
}
return caShapeLayer
}
class MyViewController : UIViewController
{
var shape1 : CAShapeLayer!
var shape2 : CAShapeLayer!
var testView : UIView!
override func loadView() {
let view = UIView()
view.backgroundColor = .white
shape1 = getDesignElementLayer(byElementID: 1)
shape1.fillColor = UIColor.green.cgColor
shape2 = getDesignElementLayer(byElementID: 2)
shape2.fillColor = UIColor.yellow.cgColor
view.layer.addSublayer(shape1)
view.layer.addSublayer(shape2)
let imageView = UIImageView(frame: CGRect(x: 0.0, y: 150.0, width: 100.0, height: 100.0))
imageView.image = render()
view.addSubview(imageView)
self.view = view
}
func render() -> UIImage
{
let resolution = CGSize(width: 100.0, height: 100.0)
let imageRenderer = UIGraphicsImageRenderer(size: resolution)
let image = imageRenderer.image { (context) in
shape1.render(in: context.cgContext)
context.cgContext.setBlendMode(.clear)
shape2.render(in: context.cgContext)
}
return image
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
编辑:CALayers可以将图像作为内容,因此示例中的CAShapeLayers仅作为示例。我需要找到任何类型的CALayers的交集。
答案 0 :(得分:0)
您可以通过剪切cgPaths而不是形状图层来实现此目的。
这是一个游乐场示例:
import UIKit
import PlaygroundSupport
func getDesignElementPath(byElementID elementID : Int) -> CGPath
{
var pth: CGPath!
switch elementID
{
case 1:
let ovalPath = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 100, height: 100))
pth = ovalPath.cgPath
case 2:
let bezierPath = UIBezierPath()
bezierPath.move(to: (CGPoint(x: 50, y: 0)))
bezierPath.addLine(to: (CGPoint(x: 0, y: 100)))
bezierPath.addLine(to: (CGPoint(x: 100, y: 100)))
bezierPath.addLine(to: (CGPoint(x: 50, y: 0)))
bezierPath.close()
pth = bezierPath.cgPath
default:
print("")
}
return pth
}
class MyViewController : UIViewController
{
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let img = renderTest()
let imageView = UIImageView(image: img)
imageView.frame.origin = CGPoint(x: 40, y: 40)
view.addSubview(imageView)
self.view = view
}
func renderTest() -> UIImage {
let size = CGSize(width: 100.0, height: 100.0)
UIGraphicsBeginImageContext(size)
guard let ctx = UIGraphicsGetCurrentContext() else { return UIImage() }
let circle = getDesignElementPath(byElementID: 1)
let triangle = getDesignElementPath(byElementID: 2)
ctx.addPath(circle)
ctx.clip()
ctx.addPath(triangle)
ctx.clip()
ctx.setFillColor(UIColor.yellow.cgColor)
ctx.fill(CGRect(x: 0, y: 0, width: size.width, height: size.height))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
结果:
编辑:
如果您想使用该形状裁剪图像,则可以将其用作遮罩。
与上述代码相同,但将viewDidLoad()
替换为:
override func loadView() {
let view = UIView()
view.backgroundColor = .white
// load a 100x100 image (of a cat)
let imgForLayer = UIImage(named: "cat100x100.jpg")
// create a 100x100 UIView at x:40 y:40
let testView = UIView(frame: CGRect(x: 40.0, y: 40.0, width: 100.0, height: 100.0))
// create an "image layer"
let imgLayer = CALayer()
// set its frame to match the view
imgLayer.frame = testView.bounds
// set its contents to the "cat" image
imgLayer.contents = imgForLayer?.cgImage
// add it as an "image sub layer"
testView.layer.addSublayer(imgLayer)
// create image with triangle / oval clip path
let img = renderTest()
// create a UIImageView from the rendered image
let maskImageView = UIImageView(image: img)
// use that image view as a mask
testView.mask = maskImageView
// add testView to the view
view.addSubview(testView)
self.view = view
}
猫图片:
结果: