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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 21:24:03