创建动画视频时,预先计算的 CAShapeLayers 不适用于遮罩

问题描述

我使用 UIBezierPath 绘制箭头形状,然后将其用作 CAShapeLayer 的路径。然后我添加了 CAShapeLayer 作为 UIImage 的掩码。我将图像切成 3 部分。这意味着添加 3 个箭头形状以制作完整图像。由于所有图像的箭头形状都相同,这就是我将所有 3 个 shapeLayer 保存到一个数组中的原因。但是当我制作动画视频并导出视频时,只有最后一张图片包含 3 个箭头形状。其他图像没有得到箭头形状。我不知道为什么会这样。但是当我在本地使用 CAShapeLayer 时,一切正常,但导出视频需要太多时间(120 秒视频的导出时间为 6 分钟)。我想为 40 个图像创建箭头形状动画。
您可以在此处查看问题 (https://drive.google.com/file/d/1LAGGxrRGASIrUmt7bv_02pbFVzGW9SWU/view?usp=sharing)
这是我的预计算 CAShapeLayers 代码

    private func preCalculateArrowShape(sliceNo : Int) {
        
        let arrowAngle : CGFloat = self.outputSize.width/2.0
        let arrowWidth : CGFloat =  (self.outputSize.width) / CGFloat(numberOfSlice - 1)
        let totalArrowWidthAdded : CGFloat =  (CGFloat(sliceNo) * arrowWidth)
        let path = UIBezierPath()
        path.move(to: CGPoint(x: self.outputSize.width - totalArrowWidthAdded,y: 0))
        
        path.addLine(to: CGPoint(x: self.outputSize.width + arrowAngle  - totalArrowWidthAdded,y: self.outputSize.height/2.0))
        path.addLine(to: CGPoint(x: self.outputSize.width - totalArrowWidthAdded,y: self.outputSize.height))
        path.addLine(to: CGPoint(x: self.outputSize.width - totalArrowWidthAdded - arrowWidth,y: self.outputSize.height))
        path.addLine(to: CGPoint(x: self.outputSize.width - totalArrowWidthAdded - arrowWidth + arrowAngle,y: self.outputSize.height/2.0))
        path.addLine(to: CGPoint(x: self.outputSize.width - totalArrowWidthAdded - arrowWidth,y: 0))
        
         path.close()
        
        let shapeLayer = CAShapeLayer()
        shapeLayer.path = path.cgPath
        shapeLayer.strokeColor = UIColor.white.cgColor
        shapeLayer.backgroundColor = UIColor.clear.cgColor
        allArrowShapeLayer.append(shapeLayer) // allArrowShapeLayer is an array of CAShapeLayer type
    }

这里我使用每个 shapeLayer 作为图像的遮罩

 private func slicePerImageAndAddAnimation(sliceNo : Int,timeIndex : Int,nextPhoto : UIImage) {
        
        let arrowWidth : CGFloat =  (self.outputSize.width) / CGFloat(numberOfSlice - 1)
        
        var totalArrowWidthAdded : CGFloat = 0.0
        totalArrowWidthAdded = (CGFloat(sliceNo) * arrowWidth)
        
        let blackLayer = CALayer()
        blackLayer.frame = CGRect(x: -self.outputSize.width,y: 0,width: self.outputSize.width - totalArrowWidthAdded,height: self.outputSize.height)
        blackLayer.backgroundColor = UIColor.clear.cgColor
        
        
        let imageLayer = CALayer()
        imageLayer.frame = CGRect(x: 0,width: self.outputSize.width,height: self.outputSize.height)
        imageLayer.contents = nextPhoto.cgImage
        blackLayer.addSublayer(imageLayer)
        
        
        
        let shapeLayer : CAShapeLayer = allArrowShapeLayer[sliceNo] /// Don't kNow why only last Image got all arrow shape mask

        imageLayer.mask = shapeLayer
        let animation = CABasicAnimation()
        animation.keyPath = "position.x"
        animation.fromValue = -self.outputSize.width
        animation.tovalue =  (self.outputSize.width - totalArrowWidthAdded)/2.0
        animation.duration = self.perImageLife/Double(self.numberOfSlice)
        animation.speed = 1 // 1 is default actually
        animation.beginTime = AVCoreAnimationBeginTimeAtZero + animationTimes[(timeIndex * numberOfSlice) + sliceNo]
        animation.fillMode = camediatimingFillMode.forwards
        animation.isRemovedOnCompletion = false
        blackLayer.add(animation,forKey: "basic")
        parentLayer.addSublayer(blackLayer)
        
        
    }

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)