【问题标题】:How to scale CALayer to fit on the video layer如何缩放 CALayer 以适应视频层
【发布时间】:2016-05-31 15:50:09
【问题描述】:

我对 CALayer 有疑问。关键是我想在电影中保存一些 UIView。基本上我正在尝试通过CALayer来做到这一点。一切正常,应用导出带有图层的电影,但带有视图的图层小于视频帧。

我尝试手动缩放图层,但它根本不像屏幕上的那样。如果我在电影中将 UIView 移得更高,它会更高。

视频具有 FullHd 帧,UIView 的层数取决于用户如何将其放置在屏幕上。

问题是: - 如何以更好的视网膜质量渲染 UIView Context?

  • 如何缩放图层以完美适应视频。

有代码:

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)
    }

我会很高兴得到帮助:)

【问题讨论】:

    标签: ios objective-c iphone swift uiview


    【解决方案1】:

    如果问题是图层显示的图像的分辨率,那么:

    • 这是您的第一个错误:UIGraphicsBeginImageContext。始终调用UIGraphicsBeginImageContextWithOptions0 的第三个参数,或显式解析。

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

    【讨论】:

    • 如果我理解正确我必须添加到每个CALayer contentScale = self.myView.layer.contentsScale?我也改了UIGraphicsBeginImageContextWithOptions(CGSizeMake(self.captionsTextView.bounds.size.width, self.captionsTextView.bounds.size.height+20), false, 0.0)。不幸的是,我不知道如何将图层调整为视频大小:(
    • 嗯,你正在做的事情已经在这里被彻底覆盖了;参见例如stackoverflow.com/questions/5997677/…,以及像raywenderlich.com/30200/…这样的教程
    【解决方案2】:

    最后,我想在视频中包含的所有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) 为什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-27
    相关资源
    最近更新 更多