如何有效地将jpeg元数据(在java中)从一个图像文件复制到另一个图像文件?



假设我有一个jpg图像文件1.jpg.
我复制了一个名为1copy.jpg.
(现在我有两个相同图像的副本)

然后分别对两个图像的EXIF属性进行一些更改所以现在两者都有不同的值,并且可能有不同的EXIF目录结构。

现在,我的目标是将1.jpg的所有EXIF元数据复制到1copy.jpg因此后面的两个文件是相同的(忽略修改日期)。在Java中如何做到这一点呢?不需要再次复制文件,也不需要重写所有的部分1 copy.jpg ?

例如,调用ExifTool将无法做到这一点,因为它将重写整个文件。

我看过的一些Java库,复制元数据属性的内容,但文件的总体EXIF目录结构可能不同,文件最终会包含相同的元数据属性和值,但不会是字节对字节的等效。

所以我想这样做的方式是以二进制模式打开文件1.jpg,在两个文件中找到EXIF部分(以FF1E开头)。从源文件逐字节地复制整个EXIF节(并且仅复制该节)到目标文件-即替换适当的EXIF节,而不重写文件的任何其他部分。

如果这种方法是好的,是否有库允许这样做?

第二个问题:我也想对mp4文件这样做。同样的策略可以使用吗?

第三个问题:只是好奇……当你在windows资源管理器中更改EXIF属性(例如标题)时,windows重写整个文件还是只是更新文件的EXIF目录部分中的条目?

JPEG的Exif段是可变长度,并包含TIFF结构。虽然在技术上可以在不重写容器文件的情况下更改Exif (TIFF)数据,但这限制了您只能更改选定的字段,或者要非常小心,以免字符串增长等。在实践中,这不是很有用。

相反,我认为大多数编辑Exif元数据的软件将替换整个Exif段,并原样从原始文件复制其他段。由于JPEG交换格式是基于段的,所以这相对容易实现。

我相信MP4格式的情况也是类似的。

类似于(伪代码):

file1 // original
file2 // modified copy
file3 // the new output
for each segment in file1
if segment is exif
copy exif from file2 to file3
else 
write segment to file3
rename file3 to file1

所以,是的,如果这是你的计划,那应该可以工作(它仍然会在技术上"重写整个文件")。虽然)。

我已经创建了一些具有类似功能的低级元数据类,作为起点可能会有所帮助,但没有提供开箱即用的功能。参见JPEGSegmentUtil和JPEGSegmentImageInputStream。

但是,如果您的目标是在操作后文件将是相同的,那么仅仅复制文件似乎更简单,更安全。


PS:还值得注意的是,Exif数据中的一些字段与图像数据的解释(颜色空间、方向、尺寸)直接相关。因此,您可能应该只复制字段的子集,或者确保图像数据在其他方面是相同的。

最新更新