4

我之前问过这个问题:How to write exif metadata to an image

我现在找到了一种注入元数据的方法。但是,它会导致将图像复制到内存中。对于大图像,并且需要在内存中已有副本,这将具有性能,并可能导致内存崩溃。

有没有正确的方法来注入元数据而不必制作图像的副本?在将其写入磁盘之后,也许可以将其附加到文件中?

如果可能的话,我更喜欢本机实现,而不必为此求助于第三方库。

4

3 回答 3

1

这个问题可能需要少量或大量代码,具体取决于您的需要。EXIF 数据存储在 JPEG APP1 标记 (FFE1) 中。它看起来非常像带有 TIFF 标题、IFD 和带有数据的单个标签的 TIFF 文件。如果您可以构建自己的 APP1 标记段,那么在 JPEG 文件中插入或替换它是微不足道的。如果您希望从现有文件中读取元数据,请添加一些新标签,然后将其写回,这可能会涉及更多内容。EXIF 数据的棘手部分是那些需要超过 4 个字节的标签。每个 TIFF 标签为 12 字节:2 字节标签、2 字节数据类型、4 字节计数、4 字节数据。如果数据不完全适合标记的 4 个字节,则标记会在文件中指定一个绝对偏移量来查找数据的位置。如果现有数据有任何带有此类数据的标签(例如,品牌、型号、捕获日期、捕获时间等),您将需要通过修复偏移量重新打包该数据,然后添加您自己的数据。简而言之:

1) 如果您要在 JPEG 文件中添加预先制作的 APP1 标记,这很简单并且只需要很少的代码。

2) 如果您需要从 JPEG 文件中读取现有的元数据,添加您自己的元数据并将其写回,代码会更复杂一些。这并不“难”,但它涉及的不仅仅是读取和写入数据块。

首先阅读 TIFF 6.0 规范以了解标签和目录结构:

TIFF 6.0 规范

接下来,看一下 JPEG EXIF 规范:

EXIF 2.2 规范

于 2012-03-27T15:09:53.717 回答
0

CGImageSourceRef 可用于获取图像属性,包括其缩略图,而无需将所有图像数据加载到内存中。这样 UIImage 和 NSData 不会浪费内存。

CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)[NSURL fileURLWithPath:path], NULL);

然后保存 CGImageDestinationRef 添加源图像和 exif 数据。

CGImageDestinationAddImageFromSource (destRef,    
                                      imageSource,
                                      0,
                                     (CFDictionaryRef)propertes );//exif
BOOL success = CGImageDestinationFinalize(destRef);
于 2012-03-31T23:04:20.107 回答
0

I would expect the existing exif manipulator software can do it, but haven't tested.

Links:

于 2012-03-29T06:47:03.300 回答