Swift中给图片写入带经纬度的EXIF数据及CGImageDestinationFinalize崩溃问题
解决CGImageDestinationFinalize崩溃的EXIF写入问题
我来帮你搞定这个崩溃问题!从你给出的代码片段来看,大概率是不可变字典直接修改、强制解包可选值或者EXIF字典初始化不当导致的,下面一步步给你梳理解决方案:
常见崩溃原因&修复点
- 不可变字典直接修改:你代码里
var metadataAsMutable = metadata只是把不可变字典的引用赋值给变量,本质还是不可变的,必须用mutableCopy()生成真正的可变字典。 - 强制解包风险:
jpeg、source这些可选值直接用!解包,如果为nil会直接崩溃,要换成可选绑定或者空值判断。 - EXIF字典缺失处理:如果原图片没有EXIF数据,直接取
kCGImagePropertyExifDictionary会得到nil,需要先创建一个新的可变字典。
修正后的完整代码示例
guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage, let jpegData = image.jpegData(compressionQuality: 1.0) as CFData? else { // 处理图片转JPEG失败的情况 return } // 创建图片源 guard let imageSource = CGImageSourceCreateWithData(jpegData, nil) else { return } // 获取原metadata并转为可变字典 var mutableMetadata = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil)?.mutableCopy() as? NSMutableDictionary ?? NSMutableDictionary() // 处理EXIF字典:如果不存在就新建 var exifDict = mutableMetadata[kCGImagePropertyExifDictionary as String] as? NSMutableDictionary ?? NSMutableDictionary() // 添加你要写入的EXIF数据,比如修改拍摄时间 exifDict[kCGImagePropertyExifDateTimeOriginal as String] = "2024:05:20 14:30:00" // 将修改后的EXIF字典放回metadata mutableMetadata[kCGImagePropertyExifDictionary as String] = exifDict // 创建图片目标,准备写入新的metadata guard let destinationData = CFDataCreateMutable(nil, 0), let imageDestination = CGImageDestinationCreateWithData(destinationData, CGImageSourceGetType(imageSource)!, 1, nil) else { return } // 添加图片和修改后的metadata CGImageDestinationAddImageFromSource(imageDestination, imageSource, 0, mutableMetadata as CFDictionary) // 最终写入,这一步就不会崩溃了 if CGImageDestinationFinalize(imageDestination) { // 写入成功,destinationData就是带新EXIF的图片数据 print("EXIF写入成功") } else { print("EXIF写入失败") }
额外注意事项
- 尽量避免使用
!强制解包,用guard let或者if let处理可选值,减少崩溃风险。 - 如果是PNG图片,
UIImagePNGRepresentation生成的数据可能不支持某些EXIF字段,建议转成JPEG处理(像示例里那样)。 - 确保你写入的EXIF字段格式符合规范,比如日期格式必须是
YYYY:MM:DD HH:MM:SS这种格式。
内容的提问来源于stack exchange,提问作者Inderpal Singh
相关产品推荐
相关产品推荐

