应用于CIFilter时,CIImage会调整大小

时间:2018-03-07 13:23:05

标签: ios swift avfoundation ciimage avvideocomposition

我正在尝试为我的视频添加全屏水印。

不幸的是,CIFilter调整了水印图像(红色矩形)的大小,我找不到使其全屏的方法。

有没有办法设置CIImage的大小?

 let watermarkFilter = CIFilter(name: "CISourceOverCompositing")!
 let watermarkImage = CIImage(image: image)


 let videoComposition = AVVideoComposition(asset: asset) { (filteringRequest) in


    let source = filteringRequest.sourceImage.clampedToExtent()

    watermarkFilter.setValue(source, forKey: "inputBackgroundImage")

    watermarkFilter.setValue(watermarkImage, forKey: "inputImage")
    let output = watermarkFilter.outputImage!

    filteringRequest.finish(with: output, context: nil)

}

Error

我也尝试过扩展CIImage,但这并没有。工作要么。

func addImageToVideo(inputURL: URL, image: UIImage,  handler: @escaping (_ exportSession: AVAssetExportSession?)-> Void) {

        let mixComposition = AVMutableComposition()
        let asset = AVAsset(url: inputURL)
        let videoTrack = asset.tracks(withMediaType: AVMediaType.video)[0]
        let timerange = CMTimeRangeMake(kCMTimeZero, asset.duration)

        let compositionVideoTrack:AVMutableCompositionTrack = mixComposition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))!

        do {
            try compositionVideoTrack.insertTimeRange(timerange, of: videoTrack, at: kCMTimeZero)
            compositionVideoTrack.preferredTransform = videoTrack.preferredTransform
        } catch {
            print(error)
        }

        let watermarkFilter = CIFilter(name: "CISourceOverCompositing")!
        let watermarkImage = CIImage(image: image)


        //Filer method
        let videoComposition = AVVideoComposition(asset: asset) { (filteringRequest) in

            let sourceImage = filteringRequest.sourceImage.clampedToExtent()

            var transform = CGAffineTransform.identity
            let scaleX = image.size.width / image.scale
            let scaleY = image.size.height / image.scale

            transform = transform.scaledBy(x: scaleX, y: scaleY)
            let transformFilter = CIFilter(name: "CIAffineClamp")!
            transformFilter.setValue( watermarkImage, forKey: "inputImage" )
            transformFilter.setValue( transform, forKey: "inputTransform")

            watermarkFilter.setValue(sourceImage, forKey: "inputBackgroundImage")
            watermarkFilter.setValue(transformFilter.outputImage, forKey: "inputImage")
            let output = watermarkFilter.outputImage!

            filteringRequest.finish(with: output, context: nil)

        }

        guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality) else {
            handler(nil)
            return
        }

        exportSession.outputURL = outputURL
        exportSession.outputFileType = AVFileType.mp4
        exportSession.shouldOptimizeForNetworkUse = true
        exportSession.videoComposition = videoComposition
        exportSession.exportAsynchronously { () -> Void in
            handler(exportSession)
        }
    }

我真的不知道该怎么做,我已经花了几周的时间尝试简单地将水印渲染成视频,但不幸的是,这只是不想工作。

1 个答案:

答案 0 :(得分:1)

我用来调整CIImage大小的一种方法是使用CIAffineClamp过滤器,这是我使用的示例:

var transform = CGAffineTransform.identity
let scaleX = sourceImage.extent.width / watermarkImage.extent.width
let scaleY = sourceImage.extent.height / watermarkImage.extent.height
transform = transform.scaledBy(x: scaleX, y: scaleY)

let transformFilter = CIFilter(name: "CIAffineClamp", withInputParameters: [:]) {
    transformFilter.setValue(watermarkImage, forKey: kCIInputImageKey)
    transformFilter.setValue(NSValue(cgAffineTransform: transform), forKey: "inputTransform")
}

然后使用您的CISourceOverCompositing过滤器,仅用于使用transformFilter.outputImage代替watermarkImage

的inputImage

只需使用比例参数即可获得结果。 如果您将获得意外结果,则表示您的源图像已旋转,因此请添加以下参数以进行修复:

transform = transform.translatedBy(x: watermarkImage.extent.midY, y: watermarkImage.extent.midX)
transform = transform.rotated(by: CGFloat(degrees * Double.pi / 180))
transform = transform.translatedBy(x: -watermarkImage.extent.midX, y: -watermarkImage.extent.midY)
transform = transform.translatedBy(x: 0.0, y: -watermarkImage.extent.x / scaleX)

如果您使用iPad,相机输出也可能不同,因此您的比例参数也会有所不同,如下所示:

if idiom == .pad {
     scaleX = sourceImage.extent.height / watermarkImage.extent.height
     scaleY = sourceImage.extent.width / watermarkImage.extent.width
} else {
     scaleX = sourceImage.extent.height / watermarkImage.extent.width
     scaleY = sourceImage.extent.width / watermarkImage.extent.height
}

前置摄像头的摄像头设置与后置摄像头不同,iPad的设置与iPhone不同,因此请彻底测试所有内容并进行相应的转换。