我正在尝试为我的视频添加全屏水印。
不幸的是,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)
}
我也尝试过扩展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)
}
}
我真的不知道该怎么做,我已经花了几周的时间尝试简单地将水印渲染成视频,但不幸的是,这只是不想工作。
答案 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
只需使用比例参数即可获得结果。 如果您将获得意外结果,则表示您的源图像已旋转,因此请添加以下参数以进行修复:
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不同,因此请彻底测试所有内容并进行相应的转换。