14

我正在开发一个正在使用的 OS X 应用程序,AVAssetImageGenerator.generateCGImagesAsynchronouslyForTimes它通常可以正常工作。但是,有时我得到的缩略图只包含前几行像素,其余的都是绿色的,有时图像会是不同深浅的绿色。很难追踪,因为它不会一直发生,但当它发生时,大约一半的缩略图会受到影响。这是我期望看到的图像:

在此处输入图像描述

但经常会发生这种情况:

在此处输入图像描述

这是我用来生成缩略图的代码:

let assetGenerator = AVAssetImageGenerator(asset: AVURLAsset(URL: url))
assetGenerator.appliesPreferredTrackTransform = true
let time = CMTime(seconds: 0, preferredTimescale: 30)

let handler: AVAssetImageGeneratorCompletionHandler = { _, image, _, res, error in
    defer { dispatch_group_leave(self.waitForThumbnail!) }

    guard let image = image where res == .Succeeded else {
        if let error = error { print(error) }
        return
    }

    let s = CGSize(width: CGImageGetWidth(image), height: CGImageGetHeight(image))
    self.thumbnail = NSImage(CGImage: image, size: s)

}

waitForThumbnail = dispatch_group_create()
dispatch_group_enter(waitForThumbnail!)

assetGenerator.maximumSize = maxThumbnailSize
assetGenerator.generateCGImagesAsynchronouslyForTimes([NSValue(CMTime: time)], completionHandler: handler)

这就是我检索缩略图的方式:

dispatch_group_wait(file.waitForThumbnail!, DISPATCH_TIME_FOREVER)
dispatch_async(dispatch_get_main_queue()) {
    self.imageView.image = file.thumbnail
}

非常感谢任何帮助,谢谢!

4

2 回答 2

7

除了使用generateCGImagesAsynchronouslyForTimesMethod 之外,您还可以使用copyCGImageAtTimeMethod 从资产中获取图像并像之前保存的那样保存该图像。这是代码。

let assetGenerator = AVAssetImageGenerator(asset: AVURLAsset(URL: url))
assetGenerator.appliesPreferredTrackTransform = true
assetGenerator.maximumSize = maxThumbnailSize
let time = CMTime(seconds: 0, preferredTimescale: 30)
do {
    let cgImage = try assetGenerator.copyCGImageAtTime(time, actualTime: nil)
    let s = CGSize(width: CGImageGetWidth(cgImage), height: CGImageGetHeight(cgImage))
    self.thumbnail = NSImage(CGImage: cgImage, size: s)    
} catch let error {
    print(error)
}
于 2016-08-16T13:19:56.647 回答
3

我认为您的问题实际上是从CGImages 返回的 sAVAssetImageGenerator.generateCGImagesAsynchronouslyForTimes没有保留。有趣的是,官方文档并没有提到这一点,但是阅读头文件时明确表示。

/*! @method generateCGImagesAsynchronouslyForTimes:completionHandler: @abstract Returns a series of CGImageRefs for an asset at or near the specified times. @param requestedTimes An NSArray of NSValues, each containing a CMTime, specifying the asset times at which an image is requested. @param handler A block that will be called when an image request is complete. @discussion Employs an efficient "batch mode" for getting images in time order. The client will receive exactly one handler callback for each requested time in requestedTimes. Changes to generator properties (snap behavior, maximum size, etc...) will not affect outstanding asynchronous image generation requests. The generated image is not retained. Clients should retain the image if they wish it to persist after the completion handler returns. */ - (void)generateCGImagesAsynchronouslyForTimes:(NSArray<NSValue *> *)requestedTimes completionHandler:(AVAssetImageGeneratorCompletionHandler)handler;

我相信保留这些CGImages 可以解决问题。

于 2018-05-12T17:10:29.283 回答