Swift:PHAsset ImageDataRequest 将 .GIF 更改为 .JPEG

Posted

技术标签:

【中文标题】Swift:PHAsset ImageDataRequest 将 .GIF 更改为 .JPEG【英文标题】:Swift: PHAsset ImageDataRequest changes .GIF to .JPEG 【发布时间】:2018-03-29 00:46:33 【问题描述】:

我尝试获取 PHAsset(视频、图像、动画 GIF)的数据。直到今天,它处理视频的效果相对较好:

PHImageManager.default().requestAVAsset(forVideo: asset, options: option, resultHandler: self.requestAVVideoAsset)

然后是图片:

PHImageManager.default().requestImage(for: asset, targetSize: imageSize, contentMode: .aspectFill, options: option, resultHandler: self.requestAVImage)

还有带有以下内容的 GIF:

PHImageManager.default().requestImageData(for: asset, options: option, resultHandler: self.requestAVPhotoAsset)

我检查 uniformTypeIdentifier 是否是 GIF,检查 PHAssetMediaType 是否是图像或视频。 这就像工厂一样,但是在 requestImageData 之后,GIF 被转换为 JPEG,我只得到一个 JPEG URL。

在照片应用中,GIF 运行良好。最初几次 GIF 都按预期工作,但经过几次测试后就停止工作了。

这是我的代码:

var isGIF = false
let resources = PHAssetResource.assetResources(for: asset)
for resource in resources 
     if resource.uniformTypeIdentifier == (kUTTypeGIF as String) 
         isGIF = true // THIS WORKS
     


if (asset.mediaType == .video) 
     let option = PHVideoRequestOptions()
     option.isNetworkAccessAllowed = true
     option.deliveryMode = PHVideoRequestOptionsDeliveryMode.highQualityFormat
                PHImageManager.default().requestAVAsset(forVideo: asset, options: option, resultHandler: self.requestAVVideoAsset)
 else 
     let option = PHImageRequestOptions()
     option.isSynchronous = false
     option.isNetworkAccessAllowed = true
     option.resizeMode = .exact
     option.deliveryMode = .highQualityFormat
     let imageSize = CGSize(width: asset.pixelWidth, height: asset.pixelHeight)

     if isGIF 
        // IS CALLED
        PHImageManager.default().requestImageData(for: asset, options: option, resultHandler: self.requestAVPhotoAsset)
      else 
        PHImageManager.default().requestImage(for: asset, targetSize: imageSize, contentMode: .aspectFill, options: option, resultHandler: self.requestAVImage)
     

然后在requestAVPhotoAsset中:

func requestAVPhotoAsset(data: Data?, type: String?, orientation: UIImageOrientation, options: [AnyHashable: Any]?) 


    // THE TYPE IS HERE: "public.jpeg"

   ...

提前谢谢你!

【问题讨论】:

【参考方案1】:

我又看了一遍,在 PHImageRequestOptions 中找到了 class member: "version"

这可以设置为“原始”,所以现在我有了这个:

let option = PHImageRequestOptions()
option.isSynchronous = false
option.isNetworkAccessAllowed = true
option.resizeMode = .exact
option.deliveryMode = .highQualityFormat
option.version = .original

这对我有用。

我认为原因是 Apple 从 ios 11 开始将 GIF 转换为图像数组,因此如果我使用原始版本,它会获取 gif 数据。 如果我错了,请纠正我,这只是一个假设!

顺便说一句。它也适用于一些具有“未调整”版本的 GIF,但不适用于所有 PHAsset。

【讨论】:

以上是关于Swift:PHAsset ImageDataRequest 将 .GIF 更改为 .JPEG的主要内容,如果未能解决你的问题,请参考以下文章

Swift 在 CollectionView 中结合 PHAsset 和 UIImage

phasset 子类型 rawValue 意味着 swift

Swift:PHAsset ImageDataRequest 将 .GIF 更改为 .JPEG

swift两种获取相册资源PHAsset的路径的方法(绝对路径)

Swift - 条件绑定的初始化程序必须具有可选类型,而不是 'PHFetchResult<PHAsset>'

从 PHAsset swift 5 IOS13 获取文件名