Ios 斯威夫特:从视频中提取图像会变得模糊,即使视频看起来很清晰?

Ios 斯威夫特:从视频中提取图像会变得模糊,即使视频看起来很清晰?,ios,swift,video,uiimage,avasset,Ios,Swift,Video,Uiimage,Avasset,下面的代码受SO上其他帖子的启发,从视频中提取图像。不幸的是,即使视频看起来清晰且完全对焦,图像看起来也很模糊 代码是否有问题,或者这是从视频中提取图像的自然困难 func getImageFromVideo(videoURL: String) -> UIImage { do { let asset = AVURLAsset(URL: NSURL(fileURLWithPath: videoURL), options: nil) let imgGen

下面的代码受SO上其他帖子的启发,从视频中提取图像。不幸的是,即使视频看起来清晰且完全对焦,图像看起来也很模糊

代码是否有问题,或者这是从视频中提取图像的自然困难

func getImageFromVideo(videoURL: String) -> UIImage {
    do {
        let asset = AVURLAsset(URL: NSURL(fileURLWithPath: videoURL), options: nil)
        let imgGenerator = AVAssetImageGenerator(asset: asset)
        imgGenerator.appliesPreferredTrackTransform = true
        let cgImage = try imgGenerator.copyCGImageAtTime(CMTimeMake(0, 1), actualTime: nil)
        let image = UIImage(CGImage: cgImage)
        return image
    } catch {
        ...
    }
}

您的代码工作正常,没有错误或问题。我试过一段视频,抓取的图像并不模糊

我会尝试使用不同的时间刻度来调试
CMTime

使用
CMTimeMake
,第一个参数是值,第二个参数是时间刻度

您的时间刻度为1,因此该值以秒为单位。值0表示1秒,值1表示2秒,以此类推。实际上,它表示时间线中指定位置后的第一帧


使用当前CMTime,它会捕获第一秒的第一帧:这是视频的第一帧(即使视频小于1秒)

如果时间刻度为4,则该值为1/4秒。等等

尝试找到一个正好落在稳定帧上的CMTime(这取决于您的视频帧速率,您必须进行测试)

例如,如果您的视频速度为24 fps,则要准确捕获一帧视频,时间刻度应为24(这样每个值单位将代表一整帧):

另一方面,您提到只有视频的第一帧和最后一帧模糊。正如您正确猜测的,这可能是您的问题的实际原因,并且是由于设备不稳定造成的


注意:视频编码也可能起到一定作用。一些MPG编码器会创建不完整的插值帧,这些帧在视频播放时会“重新创建”,但使用
copyCGImageAtTime
抓取时,这些帧可能会显得模糊。对于这个罕见的问题,我找到的唯一解决办法是在模糊的一帧之前或之后抓取另一帧

我刚刚用我的视频尝试了你的代码,提取的图像是正常的,不是模糊的。可能是视频的帧率或编码有问题?尝试抓取不同的CMTime,看看它是否仍然模糊。谢谢,您建议使用哪种CMTime?是否仅尝试了一个图像或多个图像?使用
CMTimeMake
时,第一个参数是值,第二个参数是时间刻度。您的时间刻度为1,因此该值以秒为单位:0表示1秒,1表示2秒,以此类推。如果时间刻度为4,则该值将为1/4秒。试着找到一个稳定帧的CMTime(这取决于你的视频编码和帧速率,你必须进行测试)。很酷,谢谢!关于如何根据视频编码和帧率找到稳定的帧,有什么建议吗?帧速率为24。使用当前的CMTime,它会捕获第一秒的第一帧:这是视频的第一帧(即使视频小于1秒)。//尝试使用帧率倍数的时间刻度:例如,从24开始进行测试(时间刻度为24时,第一个值表示1/24秒,对您来说应该正好是一帧)。感谢@EricD提供的所有帮助!我们选择PBJVision是因为有人说在Swift中捕获视频和图像很复杂。但从你的经验来看,这是真的吗?然而,从这篇文章来看,它一点也不复杂。使用第三方库拍摄视频和图像是否可取?不客气。//恐怕这只是一个意见问题。我的想法是:使用你现在需要的东西,你可以随时决定以后添加或删除复杂性。AVFoundation和类似的软件确实很容易与Swift一起使用,但不能做复杂的事情,也不能真正调整性能。从简单开始,必要时升级-但同样,这只是一种意见。这要视情况而定
let cgImage = try imgGenerator.copyCGImageAtTime(CMTimeMake(0, 24), actualTime: nil)