如何使用 CAKeyframeAnimation 在 swift 中绘制指定时间的矩形路径?

How can I draw rectangular paths at specified times in swift using CAKeyframeAnimation?

提问人:Dinger149 提问时间:11/16/2023 更新时间:11/16/2023 访问量:31

问:

我正在编写一个应用程序,在其中拍摄视频并通过 cormel 对象检测模型运行每一帧。通过这个模型的输出,我想在视频中每个帧的每个检测到的对象周围绘制边界框。为此,我认为我应该使用 CAKeyFrameAnimation。我的尝试如下:

    private func addBoundingBox(to layer: CALayer, videoSize: CGSize, coordinates: [[[Float]]], confidences: [[[Float]]], timeStamps: [Double]){
        let shapeLayer = CAShapeLayer()
        shapeLayer.frame = CGRect(origin: .zero, size: videoSize)
        
        let pathAnimation = CAKeyframeAnimation(keyPath: "path")
        var paths = [CGPath]()
        
        for frame in 0..<coordinates.count{
            var path = CGMutablePath()
            for i in 0..<coordinates[frame].count {
                var box = CGRect(x: Double(coordinates[frame][i][0]), y: 1 - Double(coordinates[frame][i][1]), width: Double(coordinates[frame][i][2]), height: Double(coordinates[frame][i][3]))
                
                let rectPath = CGPath(rect: LocalToShiftedPixelRect(local: box, videoSize: videoSize), transform: nil)
                path.addPath(rectPath)
            }
            paths.append(path)
        }
        
        pathAnimation.values = paths
        pathAnimation.keyTimes = timeStamps as [NSNumber]
        pathAnimation.beginTime = AVCoreAnimationBeginTimeAtZero
        
        shapeLayer.add(pathAnimation, forKey: "path")
        
        //shapeLayer.path = path
        shapeLayer.strokeColor = UIColor.red.cgColor
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.lineWidth = 3;
        
        layer.addSublayer(shapeLayer)
    }
    
    private func localToPixel(local: CGRect, videoSize: CGSize) -> CGRect{
        var pixelRect = CGRect(x: local.midX*videoSize.width, y: local.midY*videoSize.height, width: local.width*videoSize.width, height: local.height*videoSize.height)
        
        return pixelRect
    }
    
    private func ShiftForRectangleCenter(local: CGRect) -> CGRect{
        var shiftedRect = CGRect(x: local.minX - local.width/2, y: local.minY - local.height, width: local.width, height: local.height)
        
        return shiftedRect
    }
    
    private func LocalToShiftedPixelRect(local: CGRect, videoSize: CGSize) -> CGRect{
        return localToPixel(local: ShiftForRectangleCenter(local: local), videoSize: videoSize)
    }

但是,当我运行它时,我看到我的 pathAnimation 值大约前半部分显示在屏幕上,但路径动画比视频快得多,即使键值与每帧的时间戳相对应。出于某种原因,我没有看到任何应该与动画后半部分相对应的路径。

另外,对于任何对此有所了解的人,您介意分享一下您是如何学习动画系统的吗?苹果文档似乎没有太多关于这个动画的有用示例,所以我尝试过的大部分内容都来自一堆教程和堆栈溢出答案。

谢谢!

swift core-animation cashapelayer cgpath cakeyframeanimation

评论


答: 暂无答案