如何缩放CALayer以适应视频图层

3
我有一个关于CALayer的问题。我的目标是将几个UIView保存到电影中。基本上,我尝试通过CALayer来实现它。一切都没问题,应用程序导出具有层的电影,但带有视图的层比视频帧小。
我尝试手动缩放图层,但整体上看起来并不像屏幕上那样。如果我在电影中移动UIView,它会移得更高。
视频具有FullHd框架,UIView的层取决于用户在屏幕上放置的位置。
问题是: - 如何使用更好的视网膜质量渲染UIView上下文?
- 如何缩放图层以完美适配视频。
以下是代码:
VideoSaver.saveVideo(videoAsset!) { (composition, size) in
        ////////////////
        //Parent Layer//
        ////////////////

        let parentLayer = CALayer()
        parentLayer.frame = CGRectMake(0, 0, size.width, size.height)

        /////////
        //Sizes//
        /////////
        let xScaleValue = CGRectGetWidth(parentLayer.frame)/CGRectGetWidth(self.view.frame)
        let yScaleValue = CGRectGetHeight(parentLayer.frame)/CGRectGetHeight(self.view.frame)

        ///////////////
        //Video Layer//
        ///////////////
        let videoLayer = CALayer()
        videoLayer.frame = CGRectMake(0, 0, size.width, size.height)

        //////////////////
        //Captions Layer//
        //////////////////

        //Creating UIImage from Captions
        UIGraphicsBeginImageContext(CGSizeMake(self.captionsTextView.bounds.size.width, self.captionsTextView.bounds.size.height+20))
        let currentContext = UIGraphicsGetCurrentContext()

        CGContextTranslateCTM(currentContext, 0, 16)

        self.captionsTextView.layer.renderInContext(currentContext!)
        let captionTextViewImage = UIGraphicsGetImageFromCurrentImageContext()

        UIGraphicsEndImageContext()

        let captionsOverlayLayer = CALayer()
        captionsOverlayLayer.contents = captionTextViewImage.CGImage
        captionsOverlayLayer.frame = CGRectMake(self.captionsTextView.frame.origin.x * xScaleValue,
                                            (size.height - ((self.captionsTextView.frame.origin.y - 20) * yScaleValue)),
                                            CGRectGetWidth(self.captionsTextView.frame) * xScaleValue,
                                            (CGRectGetHeight(self.captionsTextView.frame)+20) * yScaleValue)

        captionsOverlayLayer.masksToBounds = true

        ///////////////////
        //TagFilter Layer//
        ///////////////////
        UIGraphicsBeginImageContext(self.tagView.bounds.size)
        self.tagView.layer.renderInContext(UIGraphicsGetCurrentContext()!)

        let tagViewImage = UIGraphicsGetImageFromCurrentImageContext()

        UIGraphicsEndImageContext()

        let tagOverlayLayer = CALayer()
        tagOverlayLayer.contents = tagViewImage.CGImage
        tagOverlayLayer.frame = CGRectMake(self.tagView.frame.origin.x * xScaleValue,
                                           (size.height - ((self.tagView.frame.origin.y) * yScaleValue)),
                                           CGRectGetWidth(self.tagView.frame) * xScaleValue,
                                           (CGRectGetHeight(self.tagView.frame)) * yScaleValue)
        ///////////////////////////////////////////////

        parentLayer.addSublayer(videoLayer)
        parentLayer.addSublayer(captionsOverlayLayer)
        parentLayer.addSublayer(tagOverlayLayer)

        ///////////////
        //Composition//
        ///////////////
        composition.animationTool = AVVideoCompositionCoreAnimationTool.init(postProcessingAsVideoLayer: videoLayer, inLayer: parentLayer)
    }

我很愿意提供帮助 :)
2个回答

1
如果问题是图层显示的图像的分辨率,那么:
  • 这是你的第一个错误:使用UIGraphicsBeginImageContext。始终调用UIGraphicsBeginImageContextWithOptions,并提供第三个参数为0或明确的分辨率。

  • 你的第二个错误是从未设置CALayer的contentsScale


ه¦‚و‍œوˆ‘çگ†è§£و­£ç،®ï¼Œوˆ‘ه؟…é،»و·»هٹ هˆ°و¯ڈن¸ھCALayer contentScale = self.myView.layer.contentsScaleï¼ںوˆ‘è؟کو›´و”¹ن؛†UIGraphicsBeginImageContextWithOptions(CGSizeMake(self.captionsTextView.bounds.size.width, self.captionsTextView.bounds.size.height+20), false, 0.0)م€‚ن¸چه¹¸çڑ„وک¯ï¼Œوˆ‘ن¸چçں¥éپ“ه¦‚ن½•ه°†ه›¾ه±‚è°ƒو•´ن¸؛视频ه¤§ه°ڈ:( - Dzeremix
你正在做的事情已经在这里得到了全面的覆盖; 例如,请参见https://dev59.com/0m025IYBdhLWcg3wc1pM,以及像https://www.raywenderlich.com/30200/avfoundation-tutorial-adding-overlays-and-animations-to-videos这样的教程。 - matt

1
在最后,我将所有我想要在视频中显示的UIViews放到一个UIView中。从那个UIView中,我创建了图层并将其缩放到视频大小。如果有人遇到同样的问题,这是代码:
VideoSaver.saveVideo(videoAsset!) 
{ 
    (composition, size) in
    ////////////////
    //Parent Layer//
    ////////////////

    let parentLayer = CALayer()
    parentLayer.frame = CGRectMake(0, 0, size.width, size.height)

    ///////////////
    //Video Layer//
    ///////////////
    let videoLayer = CALayer()
    videoLayer.frame = CGRectMake(0, 0, size.width, size.height)

    ///////////////////////
    //Effect Layout Layer//
    ///////////////////////
    UIGraphicsBeginImageContextWithOptions(self.effectLayoutView.bounds.size, false, 0.0)
    self.effectLayoutView.layer.renderInContext(UIGraphicsGetCurrentContext()!)

    let effectLayoutViewImage = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext()

    let effectOverlayLayer = CALayer()
    effectOverlayLayer.contents = effectLayoutViewImage.CGImage

    effectOverlayLayer.frame = CGRectMake(0, 0, size.width, size.height)
    effectOverlayLayer.masksToBounds = true

    ///////////////////////////////////////////////

    parentLayer.addSublayer(videoLayer)
    parentLayer.addSublayer(effectOverlayLayer)

    ///////////////
    //Composition//
    ///////////////
    composition.animationTool = AVVideoCompositionCoreAnimationTool.init(postProcessingAsVideoLayer: videoLayer, inLayer: parentLayer)
}

我遇到了同样的问题,父图层的子图层大小没有根据视频图层的大小进行调整。你能帮我吗?而且你添加了parentLayer.addSublayer(videoLayer)和parentLayer.addSublayer(effectOverlayLayer),为什么呢? - Arpan Dixit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接