CIImage 在应用于 CIFilter 时会调整大小
CIImage gets resized when applying to CIFilter
我正在尝试为我的视频添加全屏水印。
不幸的是,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)
}
}
我真的不知道该怎么做,我已经花了几个星期试图简单地将水印渲染到视频中,但不幸的是,这根本行不通。
我用来调整 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
过滤器,仅对于 inputImage 使用 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 的设置不同,因此请彻底测试所有内容并相应地应用转换。
我正在尝试为我的视频添加全屏水印。
不幸的是,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)
}
}
我真的不知道该怎么做,我已经花了几个星期试图简单地将水印渲染到视频中,但不幸的是,这根本行不通。
我用来调整 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
过滤器,仅对于 inputImage 使用 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 的设置不同,因此请彻底测试所有内容并相应地应用转换。