La image de superposition se vuelve pixelada cuando se agrega a la composition de video y se exporta

El objective es superponer una image en la parte superior de un video, pero el uso de AVVideoCompositionCoreAnimationTool pixela la image.

Las dimensiones de la image son 640×1136. Las dimensiones de export de video son 320×568 (para imitar el dispositivo 5S), por lo que la image debería networkingucirse de manera agradable. La image en sí es nítida, pero algo durante el process de export causa pixelación.

Jugar con renderScale para AVMutableVideoComposition no ayudó, ya que AVAssetExportSession lanza una exception si el valor no es 1.0.

Configuración de los contenidos La gravedad de la capa que contiene la image parece no tener efecto.

El objective es permitir que un usuario grabe video y luego dibuje en el video. (La image representa el dibujo del usuario.) En última instancia, el video exportado debe coincidir con lo que vio el usuario en la vista previa del video y con lo que el usuario dibujó, con la misma calidad y dimensiones. Esta pregunta ayuda con la pixelación de la image superpuesta.

¿Ayuda?

// Create main composition & its tracks let mainComposition = AVMutableComposition() let compositionVideoTrack = mainComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, prefernetworkingTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid)) let compositionAudioTrack = mainComposition.addMutableTrackWithMediaType(AVMediaTypeAudio, prefernetworkingTrackID: 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.networkingColor().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 

Después de realizar varias testings con rasterizationScale y contentsScale, la combinación de configuration ayudó al máximo, aunque las líneas aún no son tan nítidas como el original.

Es de esperar que alguien encuentre una respuesta sobre cómo conservar la nitidez de la image original al fusionarse con un video.

Tenga en count que probablemente también necesite shouldRasterize si usa rasterizationScale.

Estas testings se realizaron a escala de dispositivo (por ejemplo, 2.0 para 5S) y 2x escala de dispositivo (por ejemplo, 4.0 para 5S). Vio la escala del dispositivo 2x utilizada en otros lugares, así que decidí probarlo, aunque su efecto no está claro.

contentsScale 2.0: las líneas rectas eran nítidas, pero los círculos contenían artefactos.

contentsScale 4.0: las líneas rectas estaban bien pero no tan nítidas como 2.0, pero los círculos contenían less artefactos. En general una mejor image.

RasterizationScale 2.0: crestas de líneas rectas pero áreas networkingondeadas (por ejemplo, como en la letra "R") eran horribles

rasterizationScale 4.0: las líneas rectas no son tan nítidas pero las áreas networkingondeadas son mejores

rasterizationScale + contentsScale 2.0: el mejor compromiso, las líneas aún no son tan nítidas como la image original