Java 用梵语编写EXIF Xpf关键字
我一直在研究将标签写入图像的方法,类似于Windows Live照片库的工作方式。我使用过几个不同的库(metadata extractor、jhead、jheader、sanselan),但我只发现sanselan能够适应将数据写回我需要的地方 我跟随Apache到了一个T&它在更新GPS数据和孔径方面工作得非常完美 然后我尝试修改示例以更新Java 用梵语编写EXIF Xpf关键字,java,exif,Java,Exif,我一直在研究将标签写入图像的方法,类似于Windows Live照片库的工作方式。我使用过几个不同的库(metadata extractor、jhead、jheader、sanselan),但我只发现sanselan能够适应将数据写回我需要的地方 我跟随Apache到了一个T&它在更新GPS数据和孔径方面工作得非常完美 然后我尝试修改示例以更新EXIF\u TAG\u XPKEYWORDS,而不是EXIF\u TAG\u APERTURE\u VALUE 在上面链接的示例中,我将TiffOutp
EXIF\u TAG\u XPKEYWORDS
,而不是EXIF\u TAG\u APERTURE\u VALUE
在上面链接的示例中,我将TiffOutputField.create
行替换为以下内容:
String currentTagsAsString = new String((byte[]) jpegMetadata.findEXIFValue(ExifTagConstants.EXIF_TAG_XPKEYWORDS).getValue());
System.out.println("current tags: '" + currentTagsAsString + "'");
String newTag = "h e l l o";
String newTagsAsString = currentTagsAsString.trim() + " ; " + newTag + " ";
System.out.println("new desired tags: '" + newTagsAsString + "'");
TiffOutputField keywords = new TiffOutputField(ExifTagConstants.EXIF_TAG_XPKEYWORDS, FieldType.FIELD_TYPE_BYTE, newTagsAsString.length(), newTagsAsString.getBytes());
exifDirectory.removeField(ExifTagConstants.EXIF_TAG_XPKEYWORDS);
exifDirectory.add(keywords);
除了注释文字和GPS更新代码之外,其余的我都不去管了。我承认字节数组的格式让我有点困惑,这很可能就是问题所在
我没有收到任何警告/错误等。该过程正常完成,但新图像文件不包含更新的标记。为什么新图像不包含更新的标记?有更简单/更好的方法吗
更新:我编辑了代码以使用1.0 RC commons imaging API,但是结果是一样的。为了完整起见,我在这里使用了代码
如果我使用类似于
EXIF\u TAG\u XPAUTHOR
的东西,那么新代码非常有效,但是使用EXIF\u TAG\u XPKEYWORDS
不会产生任何错误、警告或消息,并且新文件根本不包含新标记数据,这不再是编写新标记的推荐方式。Microsoft XP标记是一个特别的问题,因为它们声称是byte类型,但数据实际上是UTF-16LE
而是使用新的API来解决所有这些问题-例如,我成功地用以下代码添加了XP关键字标记:
private static void rewriteXpKeywords(String fileIn, String fileOut) throws Exception {
TiffImageMetadata exif;
IImageMetadata meta = Imaging.getMetadata(new File(fileIn));
if (meta instanceof JpegImageMetadata) {
exif = ((JpegImageMetadata)meta).getExif();
} else if (meta instanceof TiffImageMetadata) {
exif = (TiffImageMetadata)meta;
} else {
return;
}
TiffOutputSet outputSet = exif.getOutputSet();
TiffOutputDirectory exifDir = outputSet.findDirectory(TiffDirectoryConstants.DIRECTORY_TYPE_EXIF);
exifDir.removeField(AllTagConstants.EXIF_TAG_XPKEYWORDS);
exifDir.add(AllTagConstants.EXIF_TAG_XPKEYWORDS, "helloworld;goodbye;");
ExifRewriter rewriter = new ExifRewriter();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File(fileOut));
rewriter.updateExifMetadataLossy(new File(fileIn), fos, outputSet);
} finally {
if (fos != null) {
fos.close();
}
}
}
你怎么知道它不会“修改数据”?你在用什么检查它?我也有同样的问题,并且得到了解决方案。你可以试试下面的代码
public static TiffOutputField getTiffOutputFieldKeyword(
TiffOutputSet outputSet, String metaDataToChange) {
TiffOutputField imageHistoryPre = outputSet
.findField(TiffConstants.EXIF_TAG_XPKEYWORDS);
if (imageHistoryPre != null) {
outputSet.removeField(TiffConstants.EXIF_TAG_XPKEYWORDS);
}
TiffOutputField tiffOutputField = new TiffOutputField(
TiffConstants.EXIF_TAG_XPKEYWORDS,
TiffFieldTypeConstants.FIELD_TYPE_BYTE,
metaDataToChange.getBytes("UTF-16").length, metaDataToChange.getBytes("UTF-16"));
return tiffOutputField;
}
我发现我的字符串格式有点不正确。原始字节数组的实际编码不包括空格字符,而是“0”字节。我已经相应地调整了代码,但仍然没有成功。你找到方法了吗?即:创建新的/更新/覆盖XPKEYWORDS?如果不是的话,我可能已经找到了。但是,我不想仅仅发布我的方法,我想将我的方法与你的方法进行比较。只是想看看有什么不同。我很喜欢新的API,但是我在更新代码时遇到了完全相同的问题。我可以很好地更新作者,但对xpkeywords的更新不会产生错误,但不会修改数据。我将更新问题,使用新的trunk commons图像。今晚我将对此进行一次尝试,但看起来没什么不同。我正在使用相同的Java代码来读取新创建的文件(从而在开始时打印现有的关键字),并且关键字与原始文件中的关键字保持不变。我刚才注意到的一个区别是,您使用的是“outputSet.findDirectory”,而不是像我的代码那样使用“outputSet.getOrCreateExifDirectory”。昨晚我在想我试图存储它的目录可能不正确。。。也许这就是问题所在。不,运气不好。我现在正在使用您的代码,其中抛出了一个println:System.out.println(exif.getFieldValue(MicrosoftTagConstants.exif_TAG_XPKEYWORDS));作为一个健全的检查,我运行了另一个测试对其中一个假定的编辑图像和转储所有目录的所有EXIF数据。。。它肯定不在里面,所以。。。我用一个新创建的图像运行了另一个测试,它运行正常。有什么线索可以解释为什么我会看到一些图片,但不是全部?
public static TiffOutputField getTiffOutputFieldKeyword(
TiffOutputSet outputSet, String metaDataToChange) {
TiffOutputField imageHistoryPre = outputSet
.findField(TiffConstants.EXIF_TAG_XPKEYWORDS);
if (imageHistoryPre != null) {
outputSet.removeField(TiffConstants.EXIF_TAG_XPKEYWORDS);
}
TiffOutputField tiffOutputField = new TiffOutputField(
TiffConstants.EXIF_TAG_XPKEYWORDS,
TiffFieldTypeConstants.FIELD_TYPE_BYTE,
metaDataToChange.getBytes("UTF-16").length, metaDataToChange.getBytes("UTF-16"));
return tiffOutputField;
}