Swift修改图片EXIF元数据时部分字段无法更新问题求助
核心问题说明
- 仅修改
kCGImagePropertyExifDateTimeDigitized字段不生效,是因为EXIF规范要求日期字段需要同步更新多处:除了你修改的数字化时间,还需要更新拍摄时间kCGImagePropertyExifDateTimeOriginal,以及TIFF属性字典下的kCGImagePropertyTIFFDateTime字段,绝大多数元数据读取工具会优先读取后两个字段的内容。 - 你使用的
DateFormatter没有指定固定的区域格式,当系统语言区域非英文时,生成的日期字符串不符合EXIF的格式要求,会被ImageIO框架自动过滤,导致写入失败。
修复后的完整代码
func writeMetadata(originalImage url: URL) { let newDestinationPath = NSTemporaryDirectory().appending("Out.jpg") let newDestinationURL = URL(fileURLWithPath: newDestinationPath) // Create source and destination guard let imageData = try? Data(contentsOf: url), let imageSource = CGImageSourceCreateWithData(imageData as CFData, nil), let uti = CGImageSourceGetType(imageSource), let destination = CGImageDestinationCreateWithURL(newDestinationURL as CFURL, uti, 1, nil) else { return } // Get original metadata guard let originalImageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as? NSDictionary, let mutableDictionary = originalImageProperties.mutableCopy() as? NSMutableDictionary else { return } // 处理EXIF字典,不存在则新建 let exifDictionary = (mutableDictionary[kCGImagePropertyExifDictionary as String] as? NSMutableDictionary) ?? NSMutableDictionary() // 处理TIFF字典,不存在则新建 let tiffDictionary = (mutableDictionary[kCGImagePropertyTIFFDictionary as String] as? NSMutableDictionary) ?? NSMutableDictionary() // 原有可成功更新的字段 exifDictionary["CameraOwnerName"] = "ADB" exifDictionary["ApertureValue"] = 1 // 修复日期格式化逻辑,指定固定区域避免格式错误 let dateFormatter = DateFormatter() dateFormatter.locale = Locale(identifier: "en_US_POSIX") dateFormatter.dateFormat = "yyyy:MM:dd HH:mm:ss" dateFormatter.timeZone = TimeZone.current // 可根据需求修改为UTC等其他时区 let targetDateStr = dateFormatter.string(from: Date()) // 同步更新三处日期字段 exifDictionary[kCGImagePropertyExifDateTimeDigitized as String] = targetDateStr exifDictionary[kCGImagePropertyExifDateTimeOriginal as String] = targetDateStr tiffDictionary[kCGImagePropertyTIFFDateTime as String] = targetDateStr // 把修改后的EXIF和TIFF字典写回元数据 mutableDictionary[kCGImagePropertyExifDictionary as String] = exifDictionary mutableDictionary[kCGImagePropertyTIFFDictionary as String] = tiffDictionary // Write new file CGImageDestinationAddImageFromSource(destination, imageSource, 0, mutableDictionary as CFDictionary) CGImageDestinationFinalize(destination) // Fetch updated metadata guard let newSource = CGImageSourceCreateWithURL(newDestinationURL as CFURL, nil), let newMetadata = CGImageSourceCopyPropertiesAtIndex(newSource, 0, nil) else { return } print("Newly updated metadata: \(newMetadata)") }
验证说明
修改后再次运行代码,打印的新元数据中可以看到三处日期字段都已更新,使用系统预览、照片App或者第三方EXIF查看工具都能正确读取到修改后的时间。
内容的提问来源于stack exchange,提问作者ADB
相关产品推荐
相关产品推荐

