错误地将 EXIF 元数据写入图像

Posted

技术标签:

【中文标题】错误地将 EXIF 元数据写入图像【英文标题】:Incorrect write EXIF metadata to image 【发布时间】:2021-12-27 11:57:58 【问题描述】:

我尝试将几个 exif 参数放到图像中,但其中只有几个是可见的。

在检查 exifDictionary 的信息时,所有参数都有一个值 [1]:https://i.stack.imgur.com/4OirK.png

但是在exiftool中查看这个文件的时候,BodySerialNumber是有效的,FileSource是不正确的值,而且DateTimeOriginal是不可见的,真的不明白是怎么回事 [2]:https://i.stack.imgur.com/mf4l4.png

这是我的代码,我尝试将元数据保存到文件中

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)
    else 
        completionHandler?(nil)
        return
    

    let exifProperties = [
        kCGImagePropertyExifBodySerialNumber as String: file.device ?? "0",
        kCGImagePropertyExifFileSource as String: file.deviceUrl ?? file.path,
        kCGImagePropertyExifDateTimeOriginal as String: "\(file.createdAt.milliseconds)"
    ] as CFDictionary
    
    let exifDictionary = [
        kCGImagePropertyExifDictionary as String: exifProperties
    ] as CFDictionary
    
    CGImageDestinationAddImageFromSource(dest, src, .zero, exifDictionary)
    if CGImageDestinationFinalize(dest) 
        completionHandler?(filePath)
     else 
        completionHandler?(nil)
    

我该如何解决?

【问题讨论】:

FileSource 不是文件名,而是输入设备的类型 @JoakimDanielson Thx,也许你知道我必须使用什么键来写入文件的原始路径? 尝试在文件上运行这个 exiftool 命令:exiftool -v2 file.png 这将为您提供数据在文件中的位置的细分。您要检查的内容是查看 EXIF 数据是否存储在 PNG eXIf 块或 PNG zTXt 块中。如果它在 zTXt 块中,那么您正在编写非标准 EXIF。在 2017 年年中之前,PNG 没有官方的 EXIF 标准,但一些程序将 EXIF 数据写入zTXt 作为一种变通方法。 exiftool Filepath 不是嵌入式标签。它是从底层文件系统中获取的文件的绝对路径。如果您检查exiftool Extra tags page,您会看到它被列为“系统”标签。 【参考方案1】:

社区维基 主要问题是因为在Java / Kotlin 中,他们可以在元键中以编程方式编写他们想要的内容,也许他们使用另一个版本的exif,我真的不知道,但在Swift 中,您可以使用特殊格式来键。 https://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html中描述的所有键

当我尝试在 kCGImagePropertyExifFileSource 字段中写入 String 时,我有 0,因为该字段必须输出整数值 1 ... 3

kCGImagePropertyExifDateTimeOriginal同样的问题,这里不仅要写String,还要特殊格式YYYY: MM: DD HH: MM: SS,其他格式不能写到这个字段!!!

我的意思是,了解字段格式和类型!)

【讨论】:

以上是关于错误地将 EXIF 元数据写入图像的主要内容,如果未能解决你的问题,请参考以下文章

在 Qt 中读取图像的 exif 元数据

Exif.js 读取图像的元数据

如何在lua中获取webp图像EXIF元数据?

Exif.js 读取图像的元数据

PHAsset 视频 EXIF 元数据检索

图像元数据信息EXIF和XMP