添加到视频合成并导出时,叠加图像会变得像素化
Posted
技术标签:
【中文标题】添加到视频合成并导出时,叠加图像会变得像素化【英文标题】:Overlay image becomes pixelated when added to video composition and exported 【发布时间】:2016-05-01 06:19:23 【问题描述】:目标是在视频上叠加图像,但使用 AVVideoCompositionCoreAnimationTool 像素化图像。
图片尺寸为 640x1136。视频导出尺寸为 320x568(模仿 5S 设备),因此图像应该可以很好地缩小。图像本身很清晰,但导出过程中的某些东西会导致像素化。
使用 AVMutableVideoComposition 的 renderScale 并没有帮助,因为如果值不是 1.0,AVAssetExportSession 会引发异常。
为保存图像的图层设置 contentsGravity 似乎没有效果。
目标是让用户录制视频然后在视频上绘图。 (图像代表用户绘图。)最终,导出的视频应该与用户在视频预览中看到的内容和用户绘制的内容相匹配,具有相同的质量和尺寸。这个问题有助于叠加图像像素化。
帮助?
// Create main composition & its tracks
let mainComposition = AVMutableComposition()
let compositionVideoTrack = mainComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))
let compositionAudioTrack = mainComposition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))
// Get source video & audio tracks
let videoURL = NSURL(fileURLWithPath: videoURL)
let videoAsset = AVURLAsset(URL: videoURL, options: nil)
let sourceVideoTrack = videoAsset.tracksWithMediaType(AVMediaTypeVideo)[0]
let sourceAudioTrack = videoAsset.tracksWithMediaType(AVMediaTypeAudio)[0]
// Add source tracks to composition
do
try compositionVideoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), ofTrack: sourceVideoTrack, atTime: kCMTimeZero)
try compositionAudioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), ofTrack: sourceAudioTrack, atTime: kCMTimeZero)
catch
print("Error with insertTimeRange while exporting video: \(error)")
// Create video composition
let videoComposition = AVMutableVideoComposition()
print("Video composition duration: \(CMTimeGetSeconds(mainComposition.duration))")
// -- Set parent layer & set size equal to device bounds
let parentLayer = CALayer()
parentLayer.frame = CGRectMake(0, 0, view.bounds.width, view.bounds.height)
parentLayer.backgroundColor = UIColor.redColor().CGColor
parentLayer.contentsGravity = kCAGravityResizeAspectFill
// -- Set composition equal to capture settings
videoComposition.renderSize = CGSize(width: view.bounds.width, height: view.bounds.height)
videoComposition.frameDuration = CMTimeMake(1, Int32(frameRate))
// -- Add instruction to video composition object
let instruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, compositionVideoTrack.asset!.duration)
let videoLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: compositionVideoTrack)
instruction.layerInstructions = [videoLayerInstruction]
videoComposition.instructions = [instruction]
// -- Create video layer
let videoLayer = CALayer()
videoLayer.frame = parentLayer.frame
videoLayer.contentsGravity = kCAGravityResizeAspectFill
// -- Create overlay layer
let overlayLayer = CALayer()
overlayLayer.frame = parentLayer.frame
overlayLayer.contentsGravity = kCAGravityResizeAspectFill
overlayLayer.contents = overlayImage!.CGImage
overlayLayer.contentsScale = overlayImage!.scale
// -- Add sublayers to parent layer
parentLayer.addSublayer(videoLayer)
parentLayer.addSublayer(overlayLayer)
//overlayLayer.shouldRasterize = true
// -- Set animation tool
videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, inLayer: parentLayer)
// Create exporter
let outputURL = getFilePath(getUniqueFilename(gMP4File))
let exporter = AVAssetExportSession(asset: mainComposition, presetName: AVAssetExportPresetHighestQuality)!
exporter.outputURL = NSURL(fileURLWithPath: outputURL)
exporter.outputFileType = AVFileTypeMPEG4
exporter.videoComposition = videoComposition
exporter.shouldOptimizeForNetworkUse = true
【问题讨论】:
【参考方案1】:在对 rasterizationScale 和 contentsScale 进行了几次测试后,将两者结合起来最有帮助,尽管线条仍然不如原来的那么清晰。
希望有人找到有关如何在与视频合并时保留原始图像清晰度的答案。
请注意,如果使用 rasterizationScale,您可能还需要 shouldRasterize。
这些测试是在设备规模(例如,5S 的 2.0)和 2x 设备规模(例如,5S 的 4.0)下进行的。看到其他地方使用了 2x 设备比例,因此决定尝试一下,尽管效果尚不清楚。
contentsScale 2.0:直线清晰,但圆圈包含伪影。
contentsScale 4.0:直线还可以,但不如 2.0 清晰,但圆圈包含的伪影更少。整体形象更好。
rasterizationScale 2.0:直线变形但圆形区域(例如,像字母“R”中的)很可怕
rasterizationScale 4.0:直线没有那么锐利,但圆形区域更好
rasterizationScale + contentsScale 2.0:最佳折衷方案,线条仍然不如原始图像清晰
【讨论】:
谢谢。现在好多了。 :)以上是关于添加到视频合成并导出时,叠加图像会变得像素化的主要内容,如果未能解决你的问题,请参考以下文章