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

iOS相册图片仅更新元数据旋转遇PHPhotosErrorDomain 3303错误

iOS图片一键旋转并更新EXIF方向的解决方案

核心问题梳理

需要实现iOS系统相册同款的图片旋转功能:仅修改图片展示方向(不编辑像素生成副本),支持恢复原图,当前遇到PHPhotosErrorDomain error 3303错误,原有方案因直接重写图片文件导致不符合需求且报错。

错误原因

3303错误通常源于编辑输出的文件与原资产的格式、元数据不匹配,或文件操作权限问题。但核心问题是实现思路偏离需求:无需旋转图片像素并保存,只需修改Photos框架中资产的方向元数据,或记录旋转操作即可。

正确实现方案

方案一:直接修改PHAsset方向(推荐,无文件重写)

该方法直接更新Photos数据库中资产的方向属性,完全不修改原图文件,符合系统相册逻辑。

private func rotateAsset(left: Bool) {
    let asset = imageAssets[selectedImageIndex]
    var targetOrientation: UIImage.Orientation
    
    // 根据当前资产方向计算目标旋转后的方向
    switch asset.orientation {
    case .up:
        targetOrientation = left ? .left : .right
    case .down:
        targetOrientation = left ? .right : .left
    case .left:
        targetOrientation = left ? .down : .up
    case .right:
        targetOrientation = left ? .up : .down
    case .upMirrored:
        targetOrientation = left ? .leftMirrored : .rightMirrored
    case .downMirrored:
        targetOrientation = left ? .rightMirrored : .leftMirrored
    case .leftMirrored:
        targetOrientation = left ? .downMirrored : .upMirrored
    case .rightMirrored:
        targetOrientation = left ? .upMirrored : .downMirrored
    @unknown default:
        targetOrientation = .up
    }
    
    // 提交方向修改请求
    PHPhotoLibrary.shared().performChanges({
        let request = PHAssetChangeRequest(for: asset)
        request.orientation = targetOrientation
    }) { success, error in
        DispatchQueue.main.async {
            if success {
                Logger.log("✅ 图片方向已更新")
                self.refreshCurrentImage()
            } else {
                Logger.log("❌ 更新方向失败: \(error?.localizedDescription ?? "未知错误")")
            }
        }
    }
}

方案二:通过编辑会话记录旋转(支持恢复原图)

若需实现类似系统相册的“恢复原图”功能,可通过PHAdjustmentData记录旋转操作,无需修改原图文件:

private func rotateWithEditSession(left: Bool) {
    let asset = imageAssets[selectedImageIndex]
    let options = PHContentEditingInputRequestOptions()
    options.isNetworkAccessAllowed = true
    
    asset.requestContentEditingInput(with: options) { editingInput, _ in
        guard let editingInput = editingInput else {
            Logger.log("❌ 无法获取编辑输入")
            return
        }
        
        // 保存旋转参数到调整数据,用于后续恢复
        let rotationInfo = ["isLeftRotation": left]
        let adjustmentData = PHAdjustmentData(
            formatIdentifier: "com.yourapp.photo-rotation", // 替换为你的APP标识
            formatVersion: "1.0",
            data: try! JSONSerialization.data(withJSONObject: rotationInfo)
        )
        
        let output = PHContentEditingOutput(contentEditingInput: editingInput)
        output.adjustmentData = adjustmentData
        
        // 提交编辑请求,无需修改原图文件
        PHPhotoLibrary.shared().performChanges({
            let request = PHAssetChangeRequest(for: asset)
            request.contentEditingOutput = output
        }) { success, error in
            DispatchQueue.main.async {
                if success {
                    Logger.log("✅ 旋转操作已记录")
                    self.refreshCurrentImage()
                } else {
                    Logger.log("❌ 记录旋转失败: \(error?.localizedDescription ?? "未知错误")")
                }
            }
        }
    }
}

替换原有代码的注意事项

  1. 移除原有旋转图片像素的rotateImage函数,无需再生成临时文件
  2. 确保已在Info.plist中添加相册读写权限:
    • NSPhotoLibraryUsageDescription
    • NSPhotoLibraryAddUsageDescription
  3. 若使用方案二,后续可通过读取PHAsset的adjustmentData来实现恢复原图功能

内容的提问来源于stack exchange,提问作者flower42

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 13:32:33