用 Java 编辑 jpeg EXIF 数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36868013/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 01:57:27  来源:igfitidea点击:

Editing jpeg EXIF data with Java

javaimagejpegexif

提问by Null Pointer

I want to edit jpg files' properties like: comments, title, date taken, camera maker, etc.

我想编辑 jpg 文件的属性,例如:评论、标题、拍摄日期、相机制造商等。

enter image description here

在此处输入图片说明

I have found libraries to read these data. But I need a freelibrary with examples to editthem.

我找到了读取这些数据的库。但是我需要一个带有示例的免费库来编辑它们。

I'm aware of apache's imaging (sanselan). But I was not able to edit data with it. If you have previously used it yourself, I'd accept that as an answer only if you provide an example code other than the one in their website. Because even when I use their example I was not able to edit any property other than GPS data. After i run the code, file-properties-details still have the same values.

我知道 apache 的成像(sanselan)。但我无法用它编辑数据。如果您以前自己使用过它,那么只有在您提供他们网站上的示例代码之外的示例代码时,我才会接受它作为答案。因为即使我使用他们的示例,我也无法编辑 GPS 数据以外的任何属性。运行代码后,文件属性详细信息仍然具有相同的值。

Thanks !

谢谢 !

Note: I also tried JHeader (https://sourceforge.net/projects/jheader/) but using it as a process with -cl option still did not changed properties list.

注意:我也尝试过 JHeader ( https://sourceforge.net/projects/jheader/) 但将其用作带有 -cl 选项的进程仍然没有更改属性列表。

回答by yurko

Apache commons Imaging works for me.

Apache commons Imaging 对我有用。

I have extended the sample provided here

我已经扩展了此处提供的示例

So obviously my client code looks like this

很明显我的客户端代码看起来像这样

public static void main(String[] args) throws ImageWriteException, ImageReadException, IOException {
    new WriteExifMetadataExample().changeExifMetadata(new File("somefilename.jpg"), new File("result_file.jpg"));
}

and the extended method in WriteExifMetadataExample

以及 WriteExifMetadataExample 中的扩展方法

public void changeExifMetadata(final File jpegImageFile, final File dst)
        throws IOException, ImageReadException, ImageWriteException {
    OutputStream os = null;
    boolean canThrow = false;
    try {
        TiffOutputSet outputSet = null;

        // note that metadata might be null if no metadata is found.
        final ImageMetadata metadata = Imaging.getMetadata(jpegImageFile);
        final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
        if (null != jpegMetadata) {
            // note that exif might be null if no Exif metadata is found.
            final TiffImageMetadata exif = jpegMetadata.getExif();

            if (null != exif) {
                // TiffImageMetadata class is immutable (read-only).
                // TiffOutputSet class represents the Exif data to write.
                //
                // Usually, we want to update existing Exif metadata by
                // changing
                // the values of a few fields, or adding a field.
                // In these cases, it is easiest to use getOutputSet() to
                // start with a "copy" of the fields read from the image.
                outputSet = exif.getOutputSet();
            }
        }

        // if file does not contain any exif metadata, we create an empty
        // set of exif metadata. Otherwise, we keep all of the other
        // existing tags.
        if (null == outputSet) {
            outputSet = new TiffOutputSet();
        }

        {
            // Example of how to add a field/tag to the output set.
            //
            // Note that you should first remove the field/tag if it already
            // exists in this directory, or you may end up with duplicate
            // tags. See above.
            //
            // Certain fields/tags are expected in certain Exif directories;
            // Others can occur in more than one directory (and often have a
            // different meaning in different directories).
            //
            // TagInfo constants often contain a description of what
            // directories are associated with a given tag.
            //
            final TiffOutputDirectory exifDirectory = outputSet
                    .getOrCreateExifDirectory();
            // make sure to remove old value if present (this method will
            // not fail if the tag does not exist).
            exifDirectory
                    .removeField(ExifTagConstants.EXIF_TAG_APERTURE_VALUE);
            exifDirectory.add(ExifTagConstants.EXIF_TAG_APERTURE_VALUE,
                    new RationalNumber(3, 10));
        }

        {
            // Example of how to add/update GPS info to output set.

            // New York City
            final double longitude = -74.0; // 74 degrees W (in Degrees East)
            final double latitude = 40 + 43 / 60.0; // 40 degrees N (in Degrees
            // North)

            outputSet.setGPSInDegrees(longitude, latitude);
        }



        final TiffOutputDirectory exifDirectory = outputSet
                .getOrCreateRootDirectory();
        exifDirectory
                .removeField(ExifTagConstants.EXIF_TAG_SOFTWARE);
        exifDirectory.add(ExifTagConstants.EXIF_TAG_SOFTWARE,
                "SomeKind");

        os = new FileOutputStream(dst);
        os = new BufferedOutputStream(os);

        new ExifRewriter().updateExifMetadataLossless(jpegImageFile, os,
                outputSet);

        canThrow = true;
    } finally {
        IoUtils.closeQuietly(canThrow, os);
    }
}

Please pay attention only to line where I add additional tag

请只注意我添加附加标签的行

final TiffOutputDirectory exifDirectory = outputSet
                .getOrCreateRootDirectory();
        exifDirectory
                .removeField(ExifTagConstants.EXIF_TAG_SOFTWARE);
        exifDirectory.add(ExifTagConstants.EXIF_TAG_SOFTWARE,
                "SomeKind");

as a result EXIF tag was properly added

结果是正确添加了 EXIF 标签

enter image description here

在此处输入图片说明



To change the comments tag you can do the following

要更改评论标签,您可以执行以下操作

        final TiffOutputDirectory exifDirectory = outputSet.getOrCreateRootDirectory();
        exifDirectory.removeField(MicrosoftTagConstants.EXIF_TAG_XPCOMMENT);
        exifDirectory.add(MicrosoftTagConstants.EXIF_TAG_XPCOMMENT, "SomeKind");

the full list of available constants is in the package:

可用常量的完整列表在包中:

org.apache.commons.imaging.formats.tiff.constants

enter image description here

在此处输入图片说明

回答by John Oss

Would an example like this work for you?

这样的例子对你有用吗?

I'd assume using packages like org.apache.commons.imaging.util.IoUtils and import org.apache.commons.imaging.Imaging would be of great help to you here.

我假设使用像 org.apache.commons.imaging.util.IoUtils 和 import org.apache.commons.imaging.Imaging 这样的包在这里对你有很大帮助。

回答by yurko

To change the comments tag you can do the following

要更改评论标签,您可以执行以下操作

        final TiffOutputDirectory exifDirectory = outputSet.getOrCreateRootDirectory();
        exifDirectory.removeField(MicrosoftTagConstants.EXIF_TAG_XPCOMMENT);
        exifDirectory.add(MicrosoftTagConstants.EXIF_TAG_XPCOMMENT, "SomeKind");

the full list of available constants is in the package:

可用常量的完整列表在包中:

org.apache.commons.imaging.formats.tiff.constants

enter image description here

在此处输入图片说明