如何将exif元数据注入图像中,而无需复制图像?

4
我之前曾经问过这个问题:如何向图像写入exif元数据
现在我已经找到了一种注入元数据的方法。 然而,这会导致将图像复制到内存中。 对于大型图像,并且需要在内存中已经有一份副本,这将导致性能问题,并可能导致内存崩溃。
有没有一种正确的方式可以注入元数据而不必复制图像? 也许它可以在将文件写入磁盘后附加到文件上?
如果可能的话,我更喜欢本地实现,而不必诉诸于第三方库。

如果您正在向文件添加元数据,则文件的大小将增加。为了管理这个问题,您可以将其读入内存,添加数据并写回(操作系统显然会这样做),或者编写自己的代码,每次读/写文件的较小块。 - BitBank
是的,我不想完全将它读入内存,但我所知道的所有苹果API都要求这样做。我所指的是读/写一点内容,尽管我不知道正确的格式,也不希望损坏文件。 - akaru
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规范


我将把exif数据作为NSDictionary,因此阅读不是问题。您知道有哪些库可以处理创建标记的详细信息吗?我可以理解规范,但当然我宁愿不要重复造轮子。 - akaru

0

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);

@AlexL 我该如何检索元数据中的缩略图?没有访问缩略图的“键”! - neeraj
1
@neeraj 请查看苹果公司的参考文献“从图像源创建缩略图图像”示例 http://developer.apple.com/library/ios/documentation/GraphicsImaging/Conceptual/ImageIOGuide/imageio_source/ikpg_source.html#//apple_ref/doc/uid/TP40005462-CH218-DontLinkElementID_6 - Alex L
@AlexL它说:“一些图像源文件包含您可以检索的缩略图像”。但它没有讨论任何获取它的方法。相反,它说如果缩略图不存在,这是制作它的方法。那么如果存在呢?我该怎么办? - neeraj
1
@neeraj我不知道你问题的答案,但我认为当kCGImageSourceCreateThumbnailFromImageIfAbsent为真且缩略图已经存在时,它将被重用。否则,该选项的目的是什么。 - Alex L
哇!我没有看到那部分...我只是假设它只用于制作缩略图。我没有看键名。我会尝试一下...谢谢! - neeraj
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接