【问题标题】:What to input to Generate CGImages Asynchronously异步生成 CGImage 的输入内容
【发布时间】:2018-06-11 07:30:36
【问题描述】:

在我的应用中,我想生成视频的多个缩略图,最好是高质量的缩略图。我的旧方法是执行 15 次循环,并在不同时间复制 CGImage。如下图

func generateThumbnails(_ fileURL:URL) {
    let asset = AVAsset(url: fileURL)
    let imageGenerator = AVAssetImageGenerator(asset: asset)
    imageGenerator.apertureMode = AVAssetImageGeneratorApertureMode.cleanAperture
    imageGenerator.appliesPreferredTrackTransform = true
    let duration = asset.duration
    let seconds = CMTimeGetSeconds(duration)
    let addition = seconds / 15
    var number = 1.0
    do {
        while number < seconds {
            let thumbnailCGImage = try imageGenerator.copyCGImage(at: CMTimeMake(Int64(number),1), actualTime: nil)
            let image = UIImage(cgImage: thumbnailCGImage)
            thumbnails.append(image)
            number += addition
        }
    } catch let err {
        return
    }
}

但是,在做了更多研究之后,我发现使用异步生成缩略图更合乎逻辑

let imageGenerator = AVAssetImageGenerator(asset: asset)
imageGenerator.generateCGImagesAsynchronously(forTimes: [NSValue], completionHandler: AVAssetImageGeneratorCompletionHandler)

但是,我真的不知道应该在 [NSValue] 和完成处理程序中输入什么。

我只需要解释一下如何以这种方式生成缩略图,看看这样做是否更好。

【问题讨论】:

  • 您没有阅读文档??? An array of NSValue objects, each containing a CMTime, specifying the asset times at which an image is requested.
  • 记得阅读fffffine手册!

标签: ios swift avasset avassetimagegenerator


【解决方案1】:

https://developer.apple.com/documentation/avfoundation/avassetimagegenerator/1388100-generatecgimagesasynchronously

requestedTimes NSValue 对象数组,每个对象包含一个 CMTime, 指定请求图像的资产时间。

用法:

let duration = asset.duration
let seconds = CMTimeGetSeconds(duration)
let addition = seconds / 15
var number = 1.0

var times = [NSValue]()
times.append(NSValue(time: CMTimeMake(Int64(number), 1)))
while number < seconds {
    number += addition
    times.append(NSValue(time: CMTimeMake(Int64(number), 1)))
}

struct Formatter {
    static let formatter: DateFormatter = {
        let result = DateFormatter()
        result.dateStyle = .short
        return result
    }()
}

imageGenerator.generateCGImagesAsynchronously(forTimes: times) { (requestedTime, cgImage, actualImageTime, status, error) in

    let seconds = CMTimeGetSeconds(requestedTime)
    let date = Date(timeIntervalSinceNow: seconds)
    let time = Formatter.formatter.string(from: date)

    switch status {
    case .succeeded: do {
            if let image = cgImage {
                print("Generated image for approximate time: \(time)")

                let img = UIImage(cgImage: image)
                //do something with `img`
            }
            else {
                print("Failed to generate a valid image for time: \(time)")
            }
        }

    case .failed: do {
            if let error = error {
                print("Failed to generate image with Error: \(error) for time: \(time)")
            }
            else {
                print("Failed to generate image for time: \(time)")
            }
        }

    case .cancelled: do {
        print("Image generation cancelled for time: \(time)")
        }
    }
}

【讨论】:

  • 欣赏,帮助很大。
猜你喜欢
  • 2020-10-10
  • 2019-11-16
  • 1970-01-01
  • 1970-01-01
  • 2017-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多