Image/Text overlay in video swift

前端 未结 5 2038
野趣味
野趣味 2021-01-30 15:09

I am work with image overlay for watermark effect in video using swift.I am using AVFoundation for this but somehow I am not succeed.

Following is my code

5条回答
  •  既然无缘
    2021-01-30 15:36

    To supplement, here's a function that creates CATextLayers based on an array UITextViews supplied by copying over their rotation, scale and font. Just add these to your container-layer supplied to AVVideoCompositionCoreAnimationTool:

    private static func createTextLayer(totalSize: CGSize,
                                            textView: UITextView) -> CATextLayer {
            let textLayer: CACenteredTextLayer = CACenteredTextLayer()
            textLayer.backgroundColor = UIColor.clear
            textLayer.foregroundColor = textView.textColor?.cgColor
            textLayer.masksToBounds = false
            textLayer.isWrapped = true
    
            let scale: CGFloat = UIScreen.main.scale
    
            if let font: UIFont = textView.font {
                let upscaledFont: UIFont = font.withSize(font.pointSize * scale)
                let attributedString = NSAttributedString(
                    string: textView.text,
                    attributes: [NSAttributedString.Key.font: upscaledFont,
                                 NSAttributedString.Key.foregroundColor: textView.textColor ?? UIColor.white])
                textLayer.string = attributedString
            }
    
            // Set text alignment
            let alignment: CATextLayerAlignmentMode
            switch textView.textAlignment {
            case NSTextAlignment.left:
                alignment = CATextLayerAlignmentMode.left
            case NSTextAlignment.center:
                alignment = CATextLayerAlignmentMode.center
            default:
                alignment = CATextLayerAlignmentMode.right
            }
            textLayer.alignmentMode = alignment
    
            let originalFrame: CGRect = textView.frame
    
            // Also take scale into consideration
            let targetSize: CGSize = CGSize(width: originalFrame.width * scale,
                                            height: originalFrame.height * scale)
    
            // The CALayer positioning is inverted on the Y-axes, so apply this
            let origin: CGPoint = CGPoint(x: originalFrame.origin.x * scale,
                                          y: (totalSize.height - (originalFrame.origin.y * scale)) - targetSize.height)
    
            textLayer.frame = CGRect(x: origin.x,
                                     y: origin.y,
                                     width: targetSize.width,
                                     height: targetSize.height)
    
            // Determine the scale
            textLayer.anchorPoint = CGPoint(x: 0.5,
                                            y: 0.5)
    
            var newTransform: CATransform3D = CATransform3DMakeScale(textView.transform.xScale,
                                                                     textView.transform.yScale,
                                                                     0)
    
            // Convert to degrees, invert the amount and convert back to radians to apply
            newTransform = CATransform3DRotate(newTransform,
                                               textView.transform.radiansFor3DTransform,
                                               0,
                                               0,
                                               1)
            textLayer.transform = newTransform
    
            return textLayer
    }
    

    Combine this with this subclassing of CATextLayer to center the text vertically:

    final class CACenteredTextLayer: CATextLayer {
        override func draw(in ctx: CGContext) {
            guard let attributedString = string as? NSAttributedString else { return }
    
            let height = self.bounds.size.height
            let boundingRect: CGRect = attributedString.boundingRect(
                with: CGSize(width: bounds.width,
                             height: CGFloat.greatestFiniteMagnitude),
                options: NSStringDrawingOptions.usesLineFragmentOrigin,
                context: nil)
            let yDiff: CGFloat = (height - boundingRect.size.height) / 2
    
            ctx.saveGState()
            ctx.translateBy(x: 0.0, y: yDiff)
            super.draw(in: ctx)
            ctx.restoreGState()
        }
    }
    
    private extension CGAffineTransform {
        var xScale: CGFloat {
            return sqrt((a*a) + (c*c))
        }
    
        var yScale: CGFloat {
            return sqrt((b*b) + (d*d))
        }
    
        var radiansFor3DTransform: CGFloat {
            let radians: CGFloat = atan2(b, a);
            let degrees: CGFloat = -(radians * 180 / CGFloat.pi)
            let convertedRadians: CGFloat = CGFloat(degrees * (CGFloat.pi / 180))
            return convertedRadians
        }
    }
    

提交回复
热议问题