如何从PHAsset中获取未修改的原始JPEG/HEIC格式图像文件?
从PHAsset获取无损原始JPEG/HEIC文件的解决方案
你之前使用的requestImage方法返回的是已经解码后的位图UIImage对象,当你需要存储该图像时必须进行二次编码,必然会产生画质损失,要获取原始编码的JPEG/HEIC文件可使用以下两种方案:
方法一:使用requestImageDataAndOrientation获取原始二进制数据(官方优先推荐)
该方法可以直接获取原始图像的编码二进制数据,不会经过解码、重编码流程,完全保留原始画质,是苹果官方推荐的获取原始资源的方案。
使用前需要先导入必要框架:
import Photos import ImageIO
示例代码:
let options = PHImageRequestOptions() // 若资源存储在iCloud,需设置为true允许下载 options.isNetworkAccessAllowed = true // 指定获取原始版本资源,不会加载用户编辑后的版本 options.version = .original PHImageManager.default().requestImageDataAndOrientation( for: asset, options: options ) { imageData, dataUTI, orientation, info in guard let imageData = imageData else { // 此处添加获取失败的处理逻辑 return } // imageData即为原始JPEG/HEIC的二进制数据,可直接写入文件无需二次编码 // 示例:写入沙盒Documents目录 let documentDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] // 根据UTI判断原始文件格式 let fileExtension: String switch dataUTI { case kUTTypeJPEG as String: fileExtension = "jpg" case kUTTypeHEIC as String: fileExtension = "heic" case kUTTypePNG as String: fileExtension = "png" default: fileExtension = "jpg" } let targetUrl = documentDir.appendingPathComponent("original_asset").appendingPathExtension(fileExtension) do { try imageData.write(to: targetUrl) print("原始文件写入成功:\(targetUrl)") } catch { print("文件写入失败:\(error.localizedDescription)") } }
方法二:修复requestContentEditingInput返回nil的问题
该方法返回nil通常由权限配置或参数设置错误导致,按以下方式调整即可正常获取原始文件URL:
- 确认相册权限:iOS14及以上系统如果是有限照片访问权限,需确认当前PHAsset在授权访问范围内;iOS13及以下系统建议申请读写级别的相册权限,只读权限部分场景无法获取编辑输入对象
- 正确配置请求参数,示例代码:
let editOptions = PHContentEditingInputRequestOptions() // 允许从iCloud下载原始资源 editOptions.isNetworkAccessAllowed = true // 返回true表示可处理资源调整数据,系统会返回原始资源+调整参数,不会返回渲染后的资源 editOptions.canHandleAdjustmentData = { _ in return true } asset.requestContentEditingInput(with: editOptions) { input, info in guard let input = input, let originalFileUrl = input.fullSizeImageURL else { // 此处添加获取失败的处理逻辑 return } // originalFileUrl为原始文件的临时本地路径,可直接读取数据拷贝到自定义沙盒路径使用 }
核心注意事项
- 两种方法获取的原始资源都不会经过二次编码,无画质损失
- 若资源存储在iCloud中,必须设置对应options的
isNetworkAccessAllowed为true,否则会直接返回空 - 不要使用
requestImage方法获取原始资源,该方法返回的是解码后的位图对象,仅适用于UI展示场景,不适合原始文件存储需求
内容的提问来源于stack exchange,提问作者Francesco Piraneo G.
相关产品推荐
相关产品推荐

