我试图用UIGraphicsImageRendererCGBlendModes绘制两个CALayer交叉点到UIImage,但没有成功。我尝试了所有不同图层位置的混合模式,我几乎被卡住了。
这是个好办法还是有别的办法?
我想达到的目标
ios - 画出两个CAShapeLayer的交点-LMLPHP
这是游乐场代码示例

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就是一个例子。我需要找到任何类型的炉排的交叉点。

最佳答案

可以通过剪切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()

结果:
ios - 画出两个CAShapeLayer的交点-LMLPHP
编辑:
如果你想让这个形状剪辑一个图像,你可以用它作为一个面具。
与上述代码相同,但将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
}

Cat图像:
ios - 画出两个CAShapeLayer的交点-LMLPHP
结果:
ios - 画出两个CAShapeLayer的交点-LMLPHP

关于ios - 画出两个CAShapeLayer的交点,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52667639/

10-11 14:50