【问题标题】: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

【问题讨论】:

    标签: ios swift video avfoundation calayer


    【解决方案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:最佳折衷方案,线条仍然不如原始图像清晰

    【讨论】:

    • 谢谢。现在好多了。 :)
    猜你喜欢
    • 2019-07-30
    • 2015-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    相关资源
    最近更新 更多