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