Android端向JPEG图片写入EXIF信息

Google向Android提供的android.support.media.ExifInterface及android.media.ExifInterface是无法提供写入指定的exif信息以外的字段的;


使用Apache提供的commons-imaging库

API:https://commons.apache.org/proper/commons-imaging/javadocs/api-release/org/apache/sanselan/Sanselan.html

由于当前在AS上不能直接添加Commons-imaging依赖,只能够添加Sanselan依赖;

故需要用maven的形式导入commons-imaging库;

1
2
3
4
5
6
7
8
9
10
11
<repository>
<id>apache.snapshots</id>
<name>Apache Development Snapshot Repository</name>
<url>https://repository.apache.org/content/repositories/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
1
2
3
4
5
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-imaging</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

官网的样例

资源来自:http://blog.csdn.net/baidu_34405762/article/details/52190844

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.ImageWriteException;
import org.apache.commons.imaging.Imaging;
import org.apache.commons.imaging.common.IImageMetadata;
import org.apache.commons.imaging.common.RationalNumber;
import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata;
import org.apache.commons.imaging.formats.jpeg.exif.ExifRewriter;
import org.apache.commons.imaging.formats.tiff.TiffImageMetadata;
import org.apache.commons.imaging.formats.tiff.constants.ExifTagConstants;
import org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory;
import org.apache.commons.imaging.formats.tiff.write.TiffOutputSet;
import org.apache.commons.imaging.util.IoUtils;
public class WriteExifMetadataExample {
public void removeExifMetadata(final File jpegImageFile, final File dst)
throws IOException, ImageReadException, ImageWriteException {
OutputStream os = null;
try {
os = new FileOutputStream(dst);
os = new BufferedOutputStream(os);
new ExifRewriter().removeExifMetadata(jpegImageFile, os);
} finally {
if (os != null) {
try {
os.close();
} catch (final IOException e) {
}
}
}
}
public static void main(String[] args) {
File old=new File("E://dd.jpg");
File news=new File("E://ddi.jpg");
WriteExifMetadataExample we=new WriteExifMetadataExample();
try {
we.changeExifMetadata(old,news);
} catch (ImageReadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ImageWriteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* This example illustrates how to add/update EXIF metadata in a JPEG file.
*
* @param jpegImageFile
* A source image file.
* @param dst
* The output file.
* @throws IOException
* @throws ImageReadException
* @throws ImageWriteException
*/
public void changeExifMetadata(final File jpegImageFile, final File dst)
throws IOException, ImageReadException, ImageWriteException {
OutputStream os = null;
try {
TiffOutputSet outputSet = null;
// note that metadata might be null if no metadata is found.
final IImageMetadata 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.
//
// see
// org.apache.commons.sanselan.formats.tiff.constants.AllTagConstants
//
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,
RationalNumber.factoryMethod(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);
}
// printTagValue(jpegMetadata, TiffConstants.TIFF_TAG_DATE_TIME);
os = new FileOutputStream(dst);
os = new BufferedOutputStream(os);
new ExifRewriter().updateExifMetadataLossless(jpegImageFile, os,
outputSet);
os.close();
os = null;
} finally {
if (os != null) {
try {
os.close();
} catch (final IOException e) {
}
}
}
}
/**
* This example illustrates how to remove a tag (if present) from EXIF
* metadata in a JPEG file.
*
* In this case, we remove the "aperture" tag from the EXIF metadata if
* present.
*
* @param jpegImageFile
* A source image file.
* @param dst
* The output file.
* @throws IOException
* @throws ImageReadException
* @throws ImageWriteException
*/
public void removeExifTag(final File jpegImageFile, final File dst) throws IOException,
ImageReadException, ImageWriteException {
OutputStream os = null;
try {
TiffOutputSet outputSet = null;
// note that metadata might be null if no metadata is found.
final IImageMetadata 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 (null == outputSet) {
// file does not contain any exif metadata. We don't need to
// update the file; just copy it.
IoUtils.copyFileNio(jpegImageFile, dst);
return;
}
{
// Example of how to remove a single tag/field.
// There are two ways to do this.
// Option 1: brute force
// Note that this approach is crude: Exif data is organized in
// directories. The same tag/field may appear in more than one
// directory, and have different meanings in each.
outputSet.removeField(ExifTagConstants.EXIF_TAG_APERTURE_VALUE);
// Option 2: precision
// We know the exact directory the tag should appear in, in this
// case the "exif" directory.
// One complicating factor is that in some cases, manufacturers
// will place the same tag in different directories.
// To learn which directory a tag appears in, either refer to
// the constants in ExifTagConstants.java or go to Phil Harvey's
// EXIF website.
final TiffOutputDirectory exifDirectory = outputSet
.getExifDirectory();
if (null != exifDirectory) {
exifDirectory
.removeField(ExifTagConstants.EXIF_TAG_APERTURE_VALUE);
}
}
os = new FileOutputStream(dst);
os = new BufferedOutputStream(os);
new ExifRewriter().updateExifMetadataLossless(jpegImageFile, os,
outputSet);
os.close();
os = null;
} finally {
if (os != null) {
try {
os.close();
} catch (final IOException e) {
}
}
}
}
/**
* This example illustrates how to set the GPS values in JPEG EXIF metadata.
*
* @param jpegImageFile
* A source image file.
* @param dst
* The output file.
* @throws IOException
* @throws ImageReadException
* @throws ImageWriteException
*/
public void setExifGPSTag(final File jpegImageFile, final File dst) throws IOException,
ImageReadException, ImageWriteException {
OutputStream os = null;
try {
TiffOutputSet outputSet = null;
// note that metadata might be null if no metadata is found.
final IImageMetadata 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/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);
}
os = new FileOutputStream(dst);
os = new BufferedOutputStream(os);
new ExifRewriter().updateExifMetadataLossless(jpegImageFile, os,
outputSet);
os.close();
os = null;
} finally {
if (os != null) {
try {
os.close();
} catch (final IOException e) {
}
}
}
}
}

整个流程如上;我们来单看一下这一段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public void changeExifMetadata(final File jpegImageFile, final File dst)
throws IOException, ImageReadException, ImageWriteException {
OutputStream os = null;
try {
TiffOutputSet outputSet = null;
final IImageMetadata metadata = Imaging.getMetadata(jpegImageFile);
final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
if (null != jpegMetadata) {
final TiffImageMetadata exif = jpegMetadata.getExif();
if (null != exif) {
outputSet = exif.getOutputSet();
}
}
if (null == outputSet) {
outputSet = new TiffOutputSet();
}
{
final TiffOutputDirectory exifDirectory = outputSet
.getOrCreateExifDirectory();
exifDirectory
.removeField(ExifTagConstants.EXIF_TAG_APERTURE_VALUE);
exifDirectory.add(ExifTagConstants.EXIF_TAG_APERTURE_VALUE,
RationalNumber.factoryMethod(3, 10));
}
os = new FileOutputStream(dst);
os = new BufferedOutputStream(os);
new ExifRewriter().updateExifMetadataLossless(jpegImageFile, os,
outputSet);
os.close();
os = null;
} finally {
if (os != null) {
try {
os.close();
} catch (final IOException e) {
}
}
}
}
1
2
3
exifDirectory.removeField(ExifTagConstants.EXIF_TAG_APERTURE_VALUE);
exifDirectory.add(ExifTagConstants.EXIF_TAG_APERTURE_VALUE,
RationalNumber.factoryMethod(3, 10));

该段代码将旧的Exif信息移除,并写入一段新的Exif信息;

这说明我们是能够向该文件中写入新的字段exif信息的;


那么我们再看一下ExifTagConstants.EXIF_TAG_APERTURE_VALUE;显然是ExifTagConstants的一个静态变量;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
package org.apache.commons.imaging.formats.tiff.constants;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfo;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoAscii;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoByte;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoBytes;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoDirectory;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoDouble;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoGpsText;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoLong;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoLongs;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoRational;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoRationals;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoSLong;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoSRational;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoShort;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoShortOrLong;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoShorts;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoUndefined;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoUndefineds;
import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoUnknowns;
/**
* References:
* http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html
* http://tiki-lounge.com/~raf/tiff/fields.html
* http://www.awaresystems.be/imaging/tiff/tifftags.html
*
* "Stonits": http://www.anyhere.com/gward/pixformat/tiffluv.html
*/
public final class ExifTagConstants {
public static final TagInfoAscii EXIF_TAG_INTEROPERABILITY_INDEX = new TagInfoAscii(
"InteroperabilityIndex", 0x0001, -1,
TiffDirectoryType.EXIF_DIRECTORY_INTEROP_IFD);
public static final TagInfoUndefined EXIF_TAG_INTEROPERABILITY_VERSION = new TagInfoUndefined(
"InteroperabilityVersion", 0x0002,
TiffDirectoryType.EXIF_DIRECTORY_INTEROP_IFD);
public static final TagInfoAscii EXIF_TAG_PROCESSING_SOFTWARE = new TagInfoAscii(
"ProcessingSoftware", 0x000b, -1,
TiffDirectoryType.EXIF_DIRECTORY_IFD0);
public static final TagInfoAscii EXIF_TAG_SOFTWARE = new TagInfoAscii(
"Software", 0x0131, -1,
TiffDirectoryType.EXIF_DIRECTORY_IFD0);
public static final TagInfoLong EXIF_TAG_PREVIEW_IMAGE_START_IFD0 = new TagInfoLong(
"PreviewImageStart", 0x0111,
TiffDirectoryType.EXIF_DIRECTORY_IFD0, true);
public static final TagInfoLong EXIF_TAG_PREVIEW_IMAGE_START_SUB_IFD1 = new TagInfoLong(
"PreviewImageStart", 0x0111,
TiffDirectoryType.EXIF_DIRECTORY_SUB_IFD1, true);
public static final TagInfoLong EXIF_TAG_JPG_FROM_RAW_START_SUB_IFD2 = new TagInfoLong(
"JpgFromRawStart", 0x0111,
TiffDirectoryType.EXIF_DIRECTORY_SUB_IFD2, true);
public static final TagInfoLong EXIF_TAG_PREVIEW_IMAGE_LENGTH_IFD0 = new TagInfoLong(
"PreviewImageLength", 0x0117,
TiffDirectoryType.EXIF_DIRECTORY_IFD0);
public static final TagInfoLong EXIF_TAG_PREVIEW_IMAGE_LENGTH_SUB_IFD1 = new TagInfoLong(
"PreviewImageLength", 0x0117,
TiffDirectoryType.EXIF_DIRECTORY_SUB_IFD1);
public static final TagInfoLong EXIF_TAG_JPG_FROM_RAW_LENGTH_SUB_IFD2 = new TagInfoLong(
"JpgFromRawLength", 0x0117,
TiffDirectoryType.EXIF_DIRECTORY_SUB_IFD2);
public static final TagInfoLong EXIF_TAG_PREVIEW_IMAGE_START_MAKER_NOTES = new TagInfoLong(
"PreviewImageStart", 0x0201,
TiffDirectoryType.EXIF_DIRECTORY_MAKER_NOTES);
public static final TagInfoLong EXIF_TAG_JPG_FROM_RAW_START_SUB_IFD = new TagInfoLong(
"JpgFromRawStart", 0x0201,
TiffDirectoryType.EXIF_DIRECTORY_SUB_IFD, true);
public static final TagInfoLong EXIF_TAG_JPG_FROM_RAW_START_IFD2 = new TagInfoLong(
"JpgFromRawStart", 0x0201,
TiffDirectoryType.EXIF_DIRECTORY_IFD2, true);
public static final TagInfoLong EXIF_TAG_OTHER_IMAGE_START = new TagInfoLong(
"OtherImageStart", 0x0201,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN, true);
public static final TagInfoLong EXIF_TAG_PREVIEW_IMAGE_LENGTH_MAKER_NOTES = new TagInfoLong(
"PreviewImageLength", 0x0202,
TiffDirectoryType.EXIF_DIRECTORY_MAKER_NOTES);
public static final TagInfoLong EXIF_TAG_JPG_FROM_RAW_LENGTH_SUB_IFD = new TagInfoLong(
"JpgFromRawLength", 0x0202,
TiffDirectoryType.EXIF_DIRECTORY_SUB_IFD);
public static final TagInfoLong EXIF_TAG_JPG_FROM_RAW_LENGTH_IFD2 = new TagInfoLong(
"JpgFromRawLength", 0x0202,
TiffDirectoryType.EXIF_DIRECTORY_IFD2);
public static final TagInfoLong EXIF_TAG_OTHER_IMAGE_LENGTH = new TagInfoLong(
"OtherImageLength", 0x0202,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoBytes EXIF_TAG_APPLICATION_NOTES = new TagInfoBytes(
"ApplicationNotes", 0x02bc, -1,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoUnknowns EXIF_TAG_MATTEING = new TagInfoUnknowns(
"Matteing", 0x80e3, -1,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoUnknowns EXIF_TAG_DATA_TYPE = new TagInfoUnknowns(
"DataType", 0x80e4, -1,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoUnknowns EXIF_TAG_IMAGE_DEPTH = new TagInfoUnknowns(
"ImageDepth", 0x80e5, -1,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoUnknowns EXIF_TAG_TILE_DEPTH = new TagInfoUnknowns(
"TileDepth", 0x80e6, -1,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoUnknowns EXIF_TAG_MODEL_2 = new TagInfoUnknowns(
"Model2", 0x827d, -1,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoRationals EXIF_TAG_EXPOSURE_TIME = new TagInfoRationals(
"ExposureTime", 0x829a, -1,
TiffDirectoryType.EXIF_DIRECTORY_EXIF_IFD);
public static final TagInfoRationals EXIF_TAG_FNUMBER = new TagInfoRationals(
"FNumber", 0x829d, -1,
TiffDirectoryType.EXIF_DIRECTORY_EXIF_IFD);
// FIXME: other types?
public static final TagInfoLong EXIF_TAG_IPTC_NAA = new TagInfoLong(
"IPTC-NAA", 0x83bb,
TiffDirectoryType.EXIF_DIRECTORY_IFD0);
public static final TagInfoShorts EXIF_TAG_INTERGRAPH_PACKET_DATA = new TagInfoShorts(
"IntergraphPacketData", 0x847e, -1,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoLongs EXIF_TAG_INTERGRAPH_FLAG_REGISTERS = new TagInfoLongs(
"IntergraphFlagRegisters", 0x847f, 16,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoAscii EXIF_TAG_SITE = new TagInfoAscii(
"Site", 0x84e0, -1,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoAscii EXIF_TAG_COLOR_SEQUENCE = new TagInfoAscii(
"ColorSequence", 0x84e1, -1,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoAscii EXIF_TAG_IT8HEADER = new TagInfoAscii(
"IT8Header", 0x84e2, -1,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoShort EXIF_TAG_RASTER_PADDING = new TagInfoShort(
"RasterPadding", 0x84e3,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoShort EXIF_TAG_BITS_PER_RUN_LENGTH = new TagInfoShort(
"BitsPerRunLength", 0x84e4,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoShort EXIF_TAG_BITS_PER_EXTENDED_RUN_LENGTH = new TagInfoShort(
"BitsPerExtendedRunLength", 0x84e5,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoBytes EXIF_TAG_COLOR_TABLE = new TagInfoBytes(
"ColorTable", 0x84e6, -1,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoByte EXIF_TAG_IMAGE_COLOR_INDICATOR = new TagInfoByte(
"ImageColorIndicator", 0x84e7,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoByte EXIF_TAG_BACKGROUND_COLOR_INDICATOR = new TagInfoByte(
"BackgroundColorIndicator", 0x84e8,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoBytes EXIF_TAG_IMAGE_COLOR_VALUE = new TagInfoBytes(
"ImageColorValue", 0x84e9, -1,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoBytes EXIF_TAG_BACKGROUND_COLOR_VALUE = new TagInfoBytes(
"BackgroundColorValue", 0x84ea, -1,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoBytes EXIF_TAG_PIXEL_INTENSITY_RANGE = new TagInfoBytes(
"PixelIntensityRange", 0x84eb, -1,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoByte EXIF_TAG_TRANSPARENCY_INDICATOR = new TagInfoByte(
"TransparencyIndicator", 0x84ec,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoAscii EXIF_TAG_COLOR_CHARACTERIZATION = new TagInfoAscii(
"ColorCharacterization", 0x84ed, -1,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoShortOrLong EXIF_TAG_HCUSAGE = new TagInfoShortOrLong(
"HCUsage", 0x84ee, 1,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoAscii EXIF_TAG_SEMINFO = new TagInfoAscii(
"SEMInfo", 0x8546, 1,
TiffDirectoryType.EXIF_DIRECTORY_IFD0);
public static final TagInfoLong EXIF_TAG_AFCP_IPTC = new TagInfoLong(
"AFCP_IPTC", 0x8568,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoLong EXIF_TAG_LEAF_DATA = new TagInfoLong(
"LeafData", 0x8606,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoBytes EXIF_TAG_PHOTOSHOP_SETTINGS = new TagInfoBytes(
"PhotoshopSettings", 0x8649, -1,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoDirectory EXIF_TAG_EXIF_OFFSET = new TagInfoDirectory(
"ExifOffset", 0x8769,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
public static final TagInfoShort EXIF_TAG_EXPOSURE_PROGRAM = new TagInfoShort(
"ExposureProgram", 0x8822,
TiffDirectoryType.EXIF_DIRECTORY_EXIF_IFD);
public static final int EXPOSURE_PROGRAM_VALUE_MANUAL = 1;
public static final int EXPOSURE_PROGRAM_VALUE_PROGRAM_AE = 2;
public static final int EXPOSURE_PROGRAM_VALUE_APERTURE_PRIORITY_AE = 3;
public static final int EXPOSURE_PROGRAM_VALUE_SHUTTER_SPEED_PRIORITY_AE = 4;
public static final int EXPOSURE_PROGRAM_VALUE_CREATIVE_SLOW_SPEED = 5;
public static final int EXPOSURE_PROGRAM_VALUE_ACTION_HIGH_SPEED = 6;
public static final int EXPOSURE_PROGRAM_VALUE_PORTRAIT = 7;
public static final int EXPOSURE_PROGRAM_VALUE_LANDSCAPE = 8;
public static final TagInfoAscii EXIF_TAG_SPECTRAL_SENSITIVITY = new TagInfoAscii(
"SpectralSensitivity", 0x8824, -1,
TiffDirectoryType.EXIF_DIRECTORY_EXIF_IFD);
public static final TagInfoDirectory EXIF_TAG_GPSINFO = new TagInfoDirectory(
"GPSInfo", 0x8825,
TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);
...
public static final List<TagInfo> ALL_EXIF_TAGS =
Collections.unmodifiableList(Arrays.asList(
EXIF_TAG_INTEROPERABILITY_INDEX, EXIF_TAG_INTEROPERABILITY_VERSION,
EXIF_TAG_PROCESSING_SOFTWARE,
EXIF_TAG_SOFTWARE,
EXIF_TAG_PREVIEW_IMAGE_START_IFD0,
EXIF_TAG_PREVIEW_IMAGE_START_SUB_IFD1,
EXIF_TAG_JPG_FROM_RAW_START_SUB_IFD2,
EXIF_TAG_PREVIEW_IMAGE_LENGTH_IFD0,
EXIF_TAG_PREVIEW_IMAGE_LENGTH_SUB_IFD1,
EXIF_TAG_JPG_FROM_RAW_LENGTH_SUB_IFD2,
EXIF_TAG_PREVIEW_IMAGE_START_MAKER_NOTES,
EXIF_TAG_JPG_FROM_RAW_START_SUB_IFD,
EXIF_TAG_JPG_FROM_RAW_START_IFD2, EXIF_TAG_OTHER_IMAGE_START,
EXIF_TAG_PREVIEW_IMAGE_LENGTH_MAKER_NOTES,
EXIF_TAG_JPG_FROM_RAW_LENGTH_SUB_IFD,
EXIF_TAG_JPG_FROM_RAW_LENGTH_IFD2, EXIF_TAG_OTHER_IMAGE_LENGTH,
EXIF_TAG_APPLICATION_NOTES,
EXIF_TAG_MATTEING, EXIF_TAG_DATA_TYPE,
EXIF_TAG_IMAGE_DEPTH, EXIF_TAG_TILE_DEPTH, EXIF_TAG_MODEL_2,
EXIF_TAG_EXPOSURE_TIME,
EXIF_TAG_FNUMBER, EXIF_TAG_IPTC_NAA,
EXIF_TAG_INTERGRAPH_PACKET_DATA,
EXIF_TAG_INTERGRAPH_FLAG_REGISTERS,
EXIF_TAG_SITE, EXIF_TAG_COLOR_SEQUENCE,
EXIF_TAG_IT8HEADER, EXIF_TAG_RASTER_PADDING,
EXIF_TAG_BITS_PER_RUN_LENGTH,
EXIF_TAG_BITS_PER_EXTENDED_RUN_LENGTH, EXIF_TAG_COLOR_TABLE,
EXIF_TAG_IMAGE_COLOR_INDICATOR,
EXIF_TAG_BACKGROUND_COLOR_INDICATOR, EXIF_TAG_IMAGE_COLOR_VALUE,
EXIF_TAG_BACKGROUND_COLOR_VALUE, EXIF_TAG_PIXEL_INTENSITY_RANGE,
EXIF_TAG_TRANSPARENCY_INDICATOR, EXIF_TAG_COLOR_CHARACTERIZATION,
EXIF_TAG_HCUSAGE, EXIF_TAG_SEMINFO, EXIF_TAG_AFCP_IPTC,
EXIF_TAG_LEAF_DATA,
EXIF_TAG_PHOTOSHOP_SETTINGS, EXIF_TAG_EXIF_OFFSET,
EXIF_TAG_EXPOSURE_PROGRAM,
EXIF_TAG_SPECTRAL_SENSITIVITY, EXIF_TAG_GPSINFO, EXIF_TAG_ISO,
EXIF_TAG_OPTO_ELECTRIC_CONV_FACTOR,
EXIF_TAG_LEAF_SUB_IFD,
EXIF_TAG_EXIF_VERSION, EXIF_TAG_DATE_TIME_ORIGINAL,
EXIF_TAG_DATE_TIME_DIGITIZED, EXIF_TAG_COMPONENTS_CONFIGURATION,
EXIF_TAG_COMPRESSED_BITS_PER_PIXEL, EXIF_TAG_SHUTTER_SPEED_VALUE,
EXIF_TAG_APERTURE_VALUE, EXIF_TAG_BRIGHTNESS_VALUE,
EXIF_TAG_EXPOSURE_COMPENSATION, EXIF_TAG_MAX_APERTURE_VALUE,
EXIF_TAG_SUBJECT_DISTANCE, EXIF_TAG_IMAGE_UNIQUE_ID,
EXIF_TAG_CAMERA_OWNER_NAME,
EXIF_TAG_BODY_SERIAL_NUMBER,
EXIF_TAG_LENS_SPECIFICATION,
EXIF_TAG_LENS_MAKE,
EXIF_TAG_LENS_MODEL,
EXIF_TAG_LENS_SERIAL_NUMBER,
EXIF_TAG_METERING_MODE,
EXIF_TAG_LIGHT_SOURCE, EXIF_TAG_FLASH, EXIF_TAG_FOCAL_LENGTH,
EXIF_TAG_SUBJECT_AREA,
EXIF_TAG_STO_NITS, EXIF_TAG_SUB_SEC_TIME,
EXIF_TAG_SUB_SEC_TIME_ORIGINAL, EXIF_TAG_SUB_SEC_TIME_DIGITIZED,
EXIF_TAG_FLASHPIX_VERSION,
EXIF_TAG_EXIF_IMAGE_WIDTH, EXIF_TAG_EXIF_IMAGE_LENGTH,
EXIF_TAG_RELATED_SOUND_FILE, EXIF_TAG_INTEROP_OFFSET,
EXIF_TAG_FLASH_ENERGY_EXIF_IFD,
EXIF_TAG_SPATIAL_FREQUENCY_RESPONSE_2, EXIF_TAG_NOISE_2,
EXIF_TAG_FOCAL_PLANE_XRESOLUTION_EXIF_IFD,
EXIF_TAG_FOCAL_PLANE_YRESOLUTION_EXIF_IFD,
EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT_EXIF_IFD,
EXIF_TAG_IMAGE_NUMBER, EXIF_TAG_SECURITY_CLASSIFICATION,
EXIF_TAG_IMAGE_HISTORY, EXIF_TAG_SUBJECT_LOCATION,
EXIF_TAG_EXPOSURE_INDEX_EXIF_IFD, EXIF_TAG_TIFF_EPSTANDARD_ID_2,
EXIF_TAG_SENSING_METHOD_EXIF_IFD, EXIF_TAG_FILE_SOURCE,
EXIF_TAG_SCENE_TYPE, EXIF_TAG_CFAPATTERN, EXIF_TAG_CUSTOM_RENDERED,
EXIF_TAG_EXPOSURE_MODE, EXIF_TAG_WHITE_BALANCE_1,
EXIF_TAG_DIGITAL_ZOOM_RATIO, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FORMAT,
EXIF_TAG_SCENE_CAPTURE_TYPE, EXIF_TAG_GAIN_CONTROL,
EXIF_TAG_CONTRAST_1, EXIF_TAG_SATURATION_1, EXIF_TAG_SHARPNESS_1,
EXIF_TAG_DEVICE_SETTING_DESCRIPTION,
EXIF_TAG_SUBJECT_DISTANCE_RANGE, EXIF_TAG_IMAGE_UNIQUE_ID,
EXIF_TAG_GAMMA,
EXIF_TAG_ANNOTATIONS, EXIF_TAG_PRINT_IM,
EXIF_TAG_OFFSET_SCHEMA, EXIF_TAG_OWNER_NAME,
EXIF_TAG_SERIAL_NUMBER, EXIF_TAG_LENS, EXIF_TAG_RAW_FILE,
EXIF_TAG_CONVERTER, EXIF_TAG_WHITE_BALANCE_2, EXIF_TAG_EXPOSURE,
EXIF_TAG_SHADOWS, EXIF_TAG_BRIGHTNESS, EXIF_TAG_CONTRAST_2,
EXIF_TAG_SATURATION_2, EXIF_TAG_SHARPNESS_2, EXIF_TAG_SMOOTHNESS,
EXIF_TAG_MOIRE_FILTER,
EXIF_TAG_USER_COMMENT, //
EXIF_TAG_MAKER_NOTE));
private ExifTagConstants() {
}
}

以上可知,ExifTagConstants.EXIF_TAG_APERTURE_VALUE是一个TagInfo变量;在TiffOutputDirectory维护了一个TiffOutputField数组保存各个exif字段;识别的标志就是TagInfo变量;

那么构造一个TagInfo变量需要:String name,int tag,TiffDirectoryType tiffDirectoryType;

这时候,我们就可以编写一个唯一的,不和已有字段重合的tag值来标志我们的新增字段;

比如:TagInfoAscii(“XXX”, 0xFFFF, -1, TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN);


在TiffOutputDirectory中add完我们需要的字段后,就是ExifRewriter变量的updateExifMetadataLossless操作了;