iOS 绿幕技术

Posted 颐和园

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS 绿幕技术相关的知识,希望对你有一定的参考价值。

绿幕(green screen)技术,又称 chroma key effect,实际上是将图片上指定颜色设置为透明的图形处理技术,这些透明区域也可以被任意背景图片替换。

这种技术在 视频合成中被广泛使用。ios 中,通过 CoreImage 的某些滤镜比如 CIBlendWithMask 可以实现这种效果,但是实现过程比较繁琐。然而功夫不负有心人,在 Github 上我们找到一个现成的实现:GitHub - quentinfasquel/MyTransparentVideoExample: A simple example of how to play a transparent video in a UIView

打开项目,可以看到一个 playdoh-bat.mp4 文件,这种视频文件具有特殊格式,并非一般的 mp4,实际上它的每一帧都可以被分成上下两部分(两帧合成一帧):

上半帧是原图,下半帧是 mask,将下半帧叠在上半帧之上,先把白色部分用上半帧的像素填充,黑色的部分用透明像素填充,形成“绿幕”效果。它的使用非常简单,通过框架提供的 AVPlayerView 类来使用它。

首先初始化一个 AVPlayerView 并添加到 View 中:

let playerView = AVPlayerView(frame: CGRect(origin: .zero, size: videoSize))
view.addSubview(playerView)

AVPlayerView 上自带了一个 AVPlayerLayer,AVPlayerView 实际上是用它来播放视频的。当然在播放之前,你需要将这个特殊的 mp4 格式合成绿幕效果应用之后的 AVPlayerItem:

let itemUrl: URL = Bundle.main.url(forResource: "playdoh-bat", withExtension: "mp4")!
let playerItem = createTransparentItem(url: itemUrl)

createTransparentItem 方法中,你需要调用 特殊的滤镜特效 AlphaFrameFilter 进行视频的合成:

		func createTransparentItem(url: URL) -> AVPlayerItem 
        let asset = AVAsset(url: url)
        let playerItem = AVPlayerItem(asset: asset)
        // Set the video so that seeking also renders with transparency
        playerItem.seekingWaitsForVideoCompositionRendering = true
        // Apply a video composition (which applies our custom filter)
        playerItem.videoComposition = createVideoComposition(for: asset)
        return playerItem
    
    
    func createVideoComposition(for asset: AVAsset) -> AVVideoComposition 
        let filter = AlphaFrameFilter(renderingMode: .builtInFilter)
        let composition = AVMutableVideoComposition(asset: asset, applyingCIFiltersWithHandler:  request in
            do 
                let (inputImage, maskImage) = request.sourceImage.verticalSplit()
                let outputImage = try filter.process(inputImage, mask: maskImage)
                return request.finish(with: outputImage, context: nil)
             catch 
                os_log("Video composition error: %s", String(describing: error))
                return request.finish(with: error)
            
        )

        composition.renderSize = asset.videoSize.applying(CGAffineTransform(scaleX: 1.0, y: 0.5))
        return composition
    

AlphaFrameFilter 类继承了 CIFilter,实现了绿幕特效(框架已经提供)。

最后播放 AVPlayItem:

				playerView.loadPlayerItem(playerItem)  [weak self] result in
            switch result 
            case .failure(let error):
                return print("Something went wrong when loading our video", error)

            case .success(let player):
                // Finally, we can start playing
                player.play()
                // Animate background
                self?.animateBackgroundColor()
            
            
        

在回调块中处理错误。最终运行效果如图:

原视频中的背景被 view controller 中的背景色(绿色)替换,可见实际上播放的是合成特效后的视频而非原视频。

以上是关于iOS 绿幕技术的主要内容,如果未能解决你的问题,请参考以下文章

Swift - iOS入口

ios OC、swift混编制作framework

ios 整理(一)swift和oc的区别

AE抠像-绿幕抠像技术-Primatte Keyer 视频教程 https://www.cgaee.com

AE抠像-绿幕抠像技术-Primatte Keyer 视频教程 https://www.cgaee.com

iOS-OC和Swift相互混合开发(OC&Swift混编)