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

iOS写入图像EXIF元数据时部分参数错误或不显示如何修复

EXIF写入异常修复方案

问题原因与对应修复方法

  • DateTimeOriginal参数丢失:EXIF标准强制要求该字段格式为YYYY:MM:DD HH:MM:SS的字符串,你当前传入的毫秒时间戳不符合格式规范,系统写入时会直接丢弃非法字段,需要先将时间转换为符合要求的格式。
  • FileSource参数值错误:kCGImagePropertyExifFileSource对应EXIF标准中的枚举类型字段,仅支持传入1/2/3三个数字值(分别对应胶片扫描、反光扫描、数码相机场景),不支持字符串类型的路径值。如果你需要存储文件路径信息,建议改用kCGImagePropertyExifUserComment等支持字符串类型的EXIF字段。
  • 优化建议:写入时优先保留原图片的元数据,仅新增/修改目标字段,避免覆盖其他默认EXIF信息。

修复后完整代码

// 提前定义EXIF专用日期格式化器,避免重复创建损耗性能
private static let exifDateFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy:MM:dd HH:mm:ss"
    formatter.timeZone = TimeZone(secondsFromGMT: 0) // 按需调整为时区,默认使用UTC时间
    formatter.locale = Locale(identifier: "en_US_POSIX") // 避免系统语言影响格式输出
    return formatter
}()

static func encodeImage(at url: URL, file: File, completionHandler: ((URL?) -> Void)?) {
    let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL
    let filePath = documentsDirectory.appendingPathComponent("\(UUID().uuidString)\(file.fileExtension ?? ".jpg")")

    guard let data = NSData(contentsOf: url),
          let src = CGImageSourceCreateWithData(data, nil),
          let uti = CGImageSourceGetType(src),
          let cfPath = CFURLCreateWithFileSystemPath(nil, filePath.path as CFString, CFURLPathStyle.cfurlposixPathStyle, false),
          let dest = CGImageDestinationCreateWithURL(cfPath, uti, 1, nil),
          // 读取原图片的元数据
          let originalProperties = CGImageSourceCopyPropertiesAtIndex(src, 0, nil) as? [String: Any]
    else {
        completionHandler?(nil)
        return
    }

    // 合并新的EXIF参数到原有元数据中
    var mutableProperties = originalProperties
    var exifDict = mutableProperties[kCGImagePropertyExifDictionary as String] as? [String: Any] ?? [:]
    // 写入机身序列号
    exifDict[kCGImagePropertyExifBodySerialNumber as String] = file.device ?? "0"
    // 写入文件路径到UserComment字段,替换原来错误的FileSource
    exifDict[kCGImagePropertyExifUserComment as String] = file.deviceUrl ?? file.path
    // 写入符合格式要求的拍摄时间
    exifDict[kCGImagePropertyExifDateTimeOriginal as String] = exifDateFormatter.string(from: file.createdAt)
    mutableProperties[kCGImagePropertyExifDictionary as String] = exifDict
    
    CGImageDestinationAddImageFromSource(dest, src, .zero, mutableProperties as CFDictionary)
    if CGImageDestinationFinalize(dest) {
        completionHandler?(filePath)
    } else {
        completionHandler?(nil)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 07:45:05