1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.imaging.formats.jpeg.exif;
18
19 import static org.junit.jupiter.api.Assertions.assertTrue;
20
21 import java.awt.image.BufferedImage;
22 import java.io.ByteArrayOutputStream;
23 import java.io.File;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.List;
27
28 import org.apache.commons.imaging.ImageFormats;
29 import org.apache.commons.imaging.ImageReadException;
30 import org.apache.commons.imaging.ImageWriteException;
31 import org.apache.commons.imaging.Imaging;
32 import org.apache.commons.imaging.common.ImageMetadata;
33 import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata;
34 import org.apache.commons.imaging.formats.jpeg.iptc.JpegIptcRewriter;
35 import org.apache.commons.imaging.formats.jpeg.xmp.JpegXmpRewriter;
36 import org.apache.commons.imaging.formats.tiff.TiffDirectory;
37 import org.apache.commons.imaging.formats.tiff.TiffImageMetadata;
38 import org.apache.commons.imaging.formats.tiff.TiffImageParser;
39 import org.apache.commons.imaging.formats.tiff.TiffImagingParameters;
40 import org.apache.commons.imaging.formats.tiff.constants.MicrosoftTagConstants;
41 import org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants;
42 import org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory;
43 import org.apache.commons.imaging.formats.tiff.write.TiffOutputSet;
44 import org.junit.jupiter.api.Test;
45
46 public class MicrosoftTagTest extends ExifBaseTest {
47 private static final String AUTHOR = "author";
48 private static final String COMMENT = "comment";
49 private static final String SUBJECT = "subject";
50 private static final String TITLE = "title";
51
52 @Test
53 public void testWrite() throws Exception {
54 final BufferedImage image = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);
55 final TiffOutputSet exifSet = new TiffOutputSet();
56 final TiffOutputDirectory root = exifSet.getOrCreateRootDirectory();
57 root.add(MicrosoftTagConstants.EXIF_TAG_XPAUTHOR, AUTHOR);
58 root.add(MicrosoftTagConstants.EXIF_TAG_XPCOMMENT, COMMENT);
59 root.add(MicrosoftTagConstants.EXIF_TAG_XPSUBJECT, SUBJECT);
60 root.add(MicrosoftTagConstants.EXIF_TAG_XPTITLE, TITLE);
61 final TiffImagingParameters params = new TiffImagingParameters();
62 params.setOutputSet(exifSet);
63 TiffImageParser tiffImageParser = new TiffImageParser();
64 final byte[] bytes;
65 try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
66 tiffImageParser.writeImage(image, baos, params);
67 bytes = baos.toByteArray();
68 }
69 checkFields(bytes);
70 }
71
72 private TiffImageMetadata toTiffMetadata(final ImageMetadata metadata) throws Exception {
73 if (metadata instanceof JpegImageMetadata) {
74 return ((JpegImageMetadata)metadata).getExif();
75 }
76 if (metadata instanceof TiffImageMetadata) {
77 return ((TiffImageMetadata)metadata);
78 }
79 throw new Exception("bad metadata format");
80 }
81
82 private byte[] cleanImage(final File imageWithExif) throws ImageReadException, ImageWriteException, IOException {
83
84 final ByteArrayOutputStream noXmp = new ByteArrayOutputStream();
85 new JpegXmpRewriter().removeXmpXml(imageWithExif, noXmp);
86 final ByteArrayOutputStream noXmpNoIptc = new ByteArrayOutputStream();
87 new JpegIptcRewriter().removeIPTC(noXmp.toByteArray(), noXmpNoIptc);
88 return noXmpNoIptc.toByteArray();
89 }
90
91 @Test
92 public void testRewrite() throws Exception {
93 final byte[] imageWithExif = cleanImage(getImageWithExifData());
94
95 final TiffImageMetadata metadata = toTiffMetadata(Imaging.getMetadata(imageWithExif));
96 final ExifRewriter rewriter = new ExifRewriter();
97 final TiffOutputSet outputSet = metadata.getOutputSet();
98 final TiffOutputDirectory root = outputSet.getOrCreateRootDirectory();
99
100
101 root.removeField(TiffTagConstants.TIFF_TAG_IMAGE_DESCRIPTION);
102 root.removeField(TiffTagConstants.TIFF_TAG_ARTIST);
103
104
105 root.removeField(MicrosoftTagConstants.EXIF_TAG_XPAUTHOR);
106 root.add(MicrosoftTagConstants.EXIF_TAG_XPAUTHOR, AUTHOR);
107
108 root.removeField(MicrosoftTagConstants.EXIF_TAG_XPCOMMENT);
109 root.add(MicrosoftTagConstants.EXIF_TAG_XPCOMMENT, COMMENT);
110
111 root.removeField(MicrosoftTagConstants.EXIF_TAG_XPSUBJECT);
112 root.add(MicrosoftTagConstants.EXIF_TAG_XPSUBJECT, SUBJECT);
113
114 root.removeField(MicrosoftTagConstants.EXIF_TAG_XPTITLE);
115 root.add(MicrosoftTagConstants.EXIF_TAG_XPTITLE, TITLE);
116
117 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
118 rewriter.updateExifMetadataLossy(imageWithExif, baos, outputSet);
119 checkFields(baos.toByteArray());
120 }
121
122 private void checkFields(final byte[] file) throws Exception {
123 final TiffImageMetadata metadata = toTiffMetadata(Imaging.getMetadata(file));
124
125
126 final List<Object> authorValues = new ArrayList<>();
127 final List<Object> commentValues = new ArrayList<>();
128 final List<Object> subjectValues = new ArrayList<>();
129 final List<Object> titleValues = new ArrayList<>();
130 for (final TiffDirectory d : metadata.contents.directories) {
131 titleValues.add(d.getFieldValue(MicrosoftTagConstants.EXIF_TAG_XPTITLE, false));
132 authorValues.add(d.getFieldValue(MicrosoftTagConstants.EXIF_TAG_XPAUTHOR, false));
133 commentValues.add(d.getFieldValue(MicrosoftTagConstants.EXIF_TAG_XPCOMMENT, false));
134 subjectValues.add(d.getFieldValue(MicrosoftTagConstants.EXIF_TAG_XPSUBJECT, false));
135 }
136
137 assertTrue(authorValues.contains(AUTHOR));
138 assertTrue(commentValues.contains(COMMENT));
139 assertTrue(subjectValues.contains(SUBJECT));
140 assertTrue(titleValues.contains(TITLE));
141 }
142 }