在 AVMutableVideoCompositionLayerInstruction 中调整视频大小
Resizing video in AVMutableVideoCompositionLayerInstruction
我正在尝试将多个视频合并为一个。每个视频可能有不同的尺寸,最终的合成尺寸可能会被用户更改。这是我的函数,它为每个要合并的视频创建一个指令。
func videoCompositionInstructionForTrack(assetTrack: AVCompositionTrack, videoSize: CGSize) -> AVMutableVideoCompositionLayerInstruction {
let instruction = AVMutableVideoCompositionLayerInstruction(assetTrack: assetTrack)
let transform = assetTrack.preferredTransform
let assetInfo = orientationFromTransform(transform: transform)
var scaleToFitRatio: CGFloat
var moveTransform: CGAffineTransform
if assetTrack.naturalSize.height/videoSize.height > assetTrack.naturalSize.width/videoSize.width {
scaleToFitRatio = videoSize.height / assetTrack.naturalSize.height
let xMoveFactor = (videoSize.width - assetTrack.naturalSize.width * scaleToFitRatio) / 2
moveTransform = CGAffineTransform(translationX: xMoveFactor, y: 0)
} else {
scaleToFitRatio = videoSize.width / assetTrack.naturalSize.width
let yMoveFactor = (videoSize.height - assetTrack.naturalSize.height * scaleToFitRatio) / 2
moveTransform = CGAffineTransform(translationX: 0, y: yMoveFactor)
}
let scaleFactor = CGAffineTransform(scaleX: scaleToFitRatio, y: scaleToFitRatio)
var concat = assetTrack.preferredTransform.concatenating(scaleFactor).concatenating(moveTransform)
if assetInfo.orientation == .down {
let fixUpsideDown = CGAffineTransform(rotationAngle: CGFloat(Double.pi))
let yFix = assetTrack.naturalSize.height + videoSize.height
let centerFix = CGAffineTransform.init(translationX: assetTrack.naturalSize.width, y: yFix)
concat = fixUpsideDown.concatenating(centerFix).concatenating(scaleFactor).concatenating(moveTransform)
}
instruction.setTransform(concat, at: kCMTimeZero)
return instruction
}
我的问题是随机颜色的额外线条有时会出现在我生成的合成的边缘。
image with lines
我看到一个答案说这样做的原因是生成的合成的大小必须由 16(或至少 2)可见。
所以这是我的问题。我怎样才能确保在应用矩阵后
let scaleFactor = CGAffineTransform(scaleX: scaleToFitRatio, y: scaleToFitRatio)
结果将是偶数,而且可以被任何东西整除?
抱歉,如果我没有提供足够的信息,感谢大家花时间尝试帮助
当缩放视频的高度最终为奇数个像素时,可能会出现 "sometimes",然后当居中时恰好使边缘位于半像素边界上。在这种情况下,您只需要降低视频的 y 原点,使其处于全像素边界。
我正在尝试将多个视频合并为一个。每个视频可能有不同的尺寸,最终的合成尺寸可能会被用户更改。这是我的函数,它为每个要合并的视频创建一个指令。
func videoCompositionInstructionForTrack(assetTrack: AVCompositionTrack, videoSize: CGSize) -> AVMutableVideoCompositionLayerInstruction {
let instruction = AVMutableVideoCompositionLayerInstruction(assetTrack: assetTrack)
let transform = assetTrack.preferredTransform
let assetInfo = orientationFromTransform(transform: transform)
var scaleToFitRatio: CGFloat
var moveTransform: CGAffineTransform
if assetTrack.naturalSize.height/videoSize.height > assetTrack.naturalSize.width/videoSize.width {
scaleToFitRatio = videoSize.height / assetTrack.naturalSize.height
let xMoveFactor = (videoSize.width - assetTrack.naturalSize.width * scaleToFitRatio) / 2
moveTransform = CGAffineTransform(translationX: xMoveFactor, y: 0)
} else {
scaleToFitRatio = videoSize.width / assetTrack.naturalSize.width
let yMoveFactor = (videoSize.height - assetTrack.naturalSize.height * scaleToFitRatio) / 2
moveTransform = CGAffineTransform(translationX: 0, y: yMoveFactor)
}
let scaleFactor = CGAffineTransform(scaleX: scaleToFitRatio, y: scaleToFitRatio)
var concat = assetTrack.preferredTransform.concatenating(scaleFactor).concatenating(moveTransform)
if assetInfo.orientation == .down {
let fixUpsideDown = CGAffineTransform(rotationAngle: CGFloat(Double.pi))
let yFix = assetTrack.naturalSize.height + videoSize.height
let centerFix = CGAffineTransform.init(translationX: assetTrack.naturalSize.width, y: yFix)
concat = fixUpsideDown.concatenating(centerFix).concatenating(scaleFactor).concatenating(moveTransform)
}
instruction.setTransform(concat, at: kCMTimeZero)
return instruction
}
我的问题是随机颜色的额外线条有时会出现在我生成的合成的边缘。 image with lines 我看到一个答案说这样做的原因是生成的合成的大小必须由 16(或至少 2)可见。 所以这是我的问题。我怎样才能确保在应用矩阵后
let scaleFactor = CGAffineTransform(scaleX: scaleToFitRatio, y: scaleToFitRatio)
结果将是偶数,而且可以被任何东西整除?
抱歉,如果我没有提供足够的信息,感谢大家花时间尝试帮助
当缩放视频的高度最终为奇数个像素时,可能会出现 "sometimes",然后当居中时恰好使边缘位于半像素边界上。在这种情况下,您只需要降低视频的 y 原点,使其处于全像素边界。