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 ?? "未知错误")") } } } } }
替换原有代码的注意事项
- 移除原有旋转图片像素的
rotateImage函数,无需再生成临时文件 - 确保已在
Info.plist中添加相册读写权限:NSPhotoLibraryUsageDescriptionNSPhotoLibraryAddUsageDescription
- 若使用方案二,后续可通过读取
PHAsset的adjustmentData来实现恢复原图功能
内容的提问来源于stack exchange,提问作者flower42
相关产品推荐
相关产品推荐

