如何使用MetaDataExtractor与XmpCore为图片XMP数据添加关键词
给JPEG图片添加/更新XMP关键词(基于MetaDataExtractor和XmpCore)
前提准备
首先确保项目中引入必要依赖(以Maven为例):
<!-- MetaDataExtractor --> <dependency> <groupId>com.drew</groupId> <artifactId>metadata-extractor</artifactId> <version>2.18.0</version> </dependency> <!-- XmpCore --> <dependency> <groupId>com.adobe.xmp</groupId> <artifactId>xmpcore</artifactId> <version>6.1.12</version> </dependency>
步骤1:读取图片并提取现有XMP数据
读取JPEG文件元数据,提取XMP数据包并解析为XmpMeta对象(无XMP数据则创建新对象):
import com.drew.imaging.ImageMetadataReader; import com.drew.metadata.Metadata; import com.drew.metadata.xmp.XmpDirectory; import com.adobe.xmp.XMPMeta; import com.adobe.xmp.XMPMetaFactory; import java.io.File; public class XmpKeywordUpdater { public static void main(String[] args) throws Exception { File imageFile = new File("path/to/your/image.jpg"); // 读取图片元数据 Metadata metadata = ImageMetadataReader.readMetadata(imageFile); // 获取XMP目录 XmpDirectory xmpDirectory = metadata.getFirstDirectoryOfType(XmpDirectory.class); XMPMeta xmpMeta; if (xmpDirectory != null && xmpDirectory.getXmpMeta() != null) { // 已有XMP数据,直接获取 xmpMeta = xmpDirectory.getXmpMeta(); } else { // 无XMP数据,创建新的XMP对象 xmpMeta = XMPMetaFactory.create(); }
步骤2:添加或更新关键词
XMP关键词存储在Dublin Core命名空间的subject字段中,支持两种修改方式:
方式1:追加新关键词
在现有关键词列表后添加新内容:
import com.adobe.xmp.schema.XmpDcConstants; // 定义要添加的关键词 String newKeyword = "风景"; // 追加到现有关键词数组 xmpMeta.appendArrayItem(XmpDcConstants.NS_DC, XmpDcConstants.PROP_SUBJECT, null, newKeyword, null);
方式2:覆盖原有关键词
清空原有关键词,替换为新的列表:
import com.adobe.xmp.schema.XmpDcConstants; // 清空原有关键词 xmpMeta.deleteProperty(XmpDcConstants.NS_DC, XmpDcConstants.PROP_SUBJECT); // 添加新的关键词列表 String[] keywords = {"风景", "户外", "日落"}; for (String keyword : keywords) { xmpMeta.appendArrayItem(XmpDcConstants.NS_DC, XmpDcConstants.PROP_SUBJECT, null, keyword, null); }
步骤3:将修改后的XMP写回JPEG文件
将修改后的XMPMeta序列化为字节流,替换或添加到JPEG的APP1段中:
import com.drew.imaging.jpeg.JpegSegmentReader; import com.drew.imaging.jpeg.JpegSegmentWriter; import com.adobe.xmp.options.SerializeOptions; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.util.List; // 将XMPMeta序列化为字节数组 SerializeOptions serializeOptions = new SerializeOptions(); serializeOptions.setOmitPacketWrapper(false); // 保留XMP数据包包装 ByteArrayOutputStream baos = new ByteArrayOutputStream(); XMPMetaFactory.serialize(xmpMeta, baos, serializeOptions); byte[] updatedXmpBytes = baos.toByteArray(); // 读取JPEG现有XMP段 List<byte[]> existingSegments = JpegSegmentReader.readSegments(imageFile, new int[]{JpegSegmentReader.SEGMENT_XMP}); // 准备写入的段:替换原有XMP或添加新段 List<byte[]> segmentsToWrite = existingSegments.isEmpty() ? List.of(updatedXmpBytes) : List.of(updatedXmpBytes); // 写回图片 try (FileOutputStream fos = new FileOutputStream(imageFile)) { JpegSegmentWriter.writeSegments(fos, JpegSegmentReader.SEGMENT_XMP, segmentsToWrite); } System.out.println("XMP关键词更新完成!"); } }
关键说明
- XMP关键词对应标准字段
dc:subject,是图像元数据的通用规范。 - 代码兼容无XMP数据的图片,会自动创建新的XMP数据包。
- 写入时替换原有XMP段,避免图片中存在多个XMP数据包导致解析异常。
内容的提问来源于stack exchange,提问作者user1229358
相关产品推荐
相关产品推荐

