You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将带人像效果遮罩的图像保存到PHPhotoLibrary是否无法实现?

问题结论

该能力不是苹果自带相机的专属API,你遇到的元数据丢失问题是PHAssetCreationRequest接口的调用方式不对导致的。

核心原因

直接调用addResource(with:data:options:)传入AVCapturePhoto的内存数据时,系统会默认过滤第三方写入的辅助元数据,仅保留视差数据,人像遮罩、深度数据都会被剥离。

两种可行解决方案

方案1:通过临时文件导入(操作最简单,兼容性最好)

你已经验证过序列化后的AVCapturePhoto写入本地文件后所有元数据完整,可以直接用这个特性实现:

  1. 将AVCapturePhoto的fileDataRepresentation()输出的原始数据直接写入沙盒临时目录,不要做任何压缩、转码操作
  2. 调用PHAssetCreationRequest的addResource(with:fileURL:options:)方法,传入临时文件的本地URL
  3. 相册写入完成后删除临时文件即可
    这个方式会让系统直接读取文件内的完整元数据,不会主动剥离人像遮罩和深度数据。

方案2:手动添加人像遮罩作为独立辅助资源

如果不想生成临时文件,可以在创建相册资源时手动添加人像遮罩数据:

PHPhotoLibrary.shared().performChanges {
    let request = PHAssetCreationRequest.forAsset()
    // 先添加主照片资源
    guard let photoData = photo.fileDataRepresentation() else { return }
    let mainOpts = PHAssetResourceCreationOptions()
    mainOpts.shouldMoveFile = false
    request.addResource(with: .photo, data: photoData, options: mainOpts)
    // 单独添加人像遮罩资源
    if let matte = photo.portraitEffectsMatte, let matteData = matte.mattingData {
        let matteOpts = PHAssetResourceCreationOptions()
        matteOpts.uniformTypeIdentifier = kUTTypePortraitEffectsMatte as String
        request.addResource(with: .auxiliary, data: matteData, options: matteOpts)
    }
} completionHandler: { success, error in
    // 处理结果
}
[PHPhotoLibrary.sharedPhotoLibrary performChanges:^{
    PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAsset];
    NSData *photoData = [photo fileDataRepresentation];
    if (!photoData) return;
    // 添加主图
    PHAssetResourceCreationOptions *mainOpts = [[PHAssetResourceCreationOptions alloc] init];
    mainOpts.shouldMoveFile = NO;
    [request addResourceWithType:PHAssetResourceTypePhoto data:photoData options:mainOpts];
    // 添加人像遮罩
    AVPortraitEffectsMatte *matte = photo.portraitEffectsMatte;
    NSData *matteData = matte.mattingData;
    if (matte && matteData) {
        PHAssetResourceCreationOptions *matteOpts = [[PHAssetResourceCreationOptions alloc] init];
        matteOpts.uniformTypeIdentifier = (__bridge NSString *)kUTTypePortraitEffectsMatte;
        [request addResourceWithType:PHAssetResourceTypeAuxiliary data:matteData options:matteOpts];
    }
} completionHandler:^(BOOL success, NSError * _Nullable error) {
    // 处理结果
}];

注意事项

  • 仅iOS 13及以上系统支持第三方应用写入人像遮罩数据,更低版本的系统确实只有系统相机可以写入该类元数据
  • 写入后可以通过PHAssetResource.assetResources(for: asset)遍历资源,检查是否存在UTI为portraitEffectsMatte的辅助资源,确认写入成功

内容的提问来源于stack exchange,提问作者Ari J.R.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 22:15:00