Commons Imaging 读取图像EXIF信息



Commons Imaging 读取图像EXIF信息。Apache Commons Imaging 前身是 Apache Commons Sanselan ,这是一个用来读写各种图像格式的 Java 类库,包括快速解析图片的基本信息(大小、色彩空间、ICC配置等)和元数据。尽管慢点但非常好的可移植性。比起 ImageIO/JAI/Toolkit 更容易使用,支持更多的格式,提供简单访问元数据的方法。javadoc

 

读取图像EXIF信息的示例代码:

 

 

 

 

 

 

001

 

package org.apache.commons.imaging.examples;

 

 

 

 

 

002

 

 

 

 

 

 

 

003

 

import java.io.BufferedOutputStream;

 

 

 

 

 

004

 

import java.io.File;

 

 

 

 

 

005

 

import java.io.FileOutputStream;

 

 

 

 

 

006

 

import java.io.IOException;

 

 

 

 

 

007

 

import java.io.OutputStream;

 

 

 

 

 

008

 

 

 

 

 

 

 

009

 

import org.apache.commons.imaging.ImageReadException;

 

 

 

 

 

010

 

import org.apache.commons.imaging.ImageWriteException;

 

 

 

 

 

011

 

import org.apache.commons.imaging.Imaging;

 

 

 

 

 

012

 

import org.apache.commons.imaging.common.IImageMetadata;

 

 

 

 

 

013

 

import org.apache.commons.imaging.common.RationalNumber;

 

 

 

 

 

014

 

import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata;

 

 

 

 

 

015

 

import org.apache.commons.imaging.formats.jpeg.exif.ExifRewriter;

 

 

 

 

 

016

 

import org.apache.commons.imaging.formats.tiff.TiffImageMetadata;

 

 

 

 

 

017

 

import org.apache.commons.imaging.formats.tiff.constants.ExifTagConstants;

 

 

 

 

 

018

 

import org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory;

 

 

 

 

 

019

 

import org.apache.commons.imaging.formats.tiff.write.TiffOutputSet;

 

 

 

 

 

020

 

import org.apache.commons.imaging.util.IoUtils;

 

 

 

 

 

021

 

 

 

 

 

 

 

022

 

public class WriteExifMetadataExample {

 

 

 

 

 

023

 

public void removeExifMetadata(final File jpegImageFile, final File dst)

 

 

 

 

 

024

 

throws IOException, ImageReadException, ImageWriteException {

 

 

 

 

 

025

 

OutputStream os = null;

 

 

 

 

 

026

 

try {

 

 

 

 

 

027

 

os = new FileOutputStream(dst);

 

 

 

 

 

028

 

os = new BufferedOutputStream(os);

 

 

 

 

 

029

 

 

 

 

 

 

 

030

 

new ExifRewriter().removeExifMetadata(jpegImageFile, os);

 

 

 

 

 

031

 

} finally {

 

 

 

 

 

032

 

if (os != null) {

 

 

 

 

 

033

 

try {

 

 

 

 

 

034

 

os.close();

 

 

 

 

 

035

 

} catch (final IOException e) {

 

 

 

 

 

036

 

 

 

 

 

 

 

037

 

}

 

 

 

 

 

038

 

}

 

 

 

 

 

039

 

}

 

 

 

 

 

040

 

}

 

 

 

 

 

041

 

 

 

 

 

 

 

042

 

/**

 

 

 

 

 

043

 

* This example illustrates how to add/update EXIF metadata in a JPEG file.

 

 

 

 

 

044

 

*

 

 

 

 

 

045

 

* @param jpegImageFile

 

 

 

 

 

046

 

* A source image file.

 

 

 

 

 

047

 

* @param dst

 

 

 

 

 

048

 

* The output file.

 

 

 

 

 

049

 

* @throws IOException

 

 

 

 

 

050

 

* @throws ImageReadException

 

 

 

 

 

051

 

* @throws ImageWriteException

 

 

 

 

 

052

 

*/

 

 

 

 

 

053

 

public void changeExifMetadata(final File jpegImageFile, final File dst)

 

 

 

 

 

054

 

throws IOException, ImageReadException, ImageWriteException {

 

 

 

 

 

055

 

OutputStream os = null;

 

 

 

 

 

056

 

try {

 

 

 

 

 

057

 

TiffOutputSet outputSet = null;

 

 

 

 

 

058

 

 

 

 

 

 

 

059

 

// note that metadata might be null if no metadata is found.

 

 

 

 

 

060

 

final IImageMetadata metadata = Imaging.getMetadata(jpegImageFile);

 

 

 

 

 

061

 

final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;

 

 

 

 

 

062

 

if (null != jpegMetadata) {

 

 

 

 

 

063

 

// note that exif might be null if no Exif metadata is found.

 

 

 

 

 

064

 

final TiffImageMetadata exif = jpegMetadata.getExif();

 

 

 

 

 

065

 

 

 

 

 

 

 

066

 

if (null != exif) {

 

 

 

 

 

067

 

// TiffImageMetadata class is immutable (read-only).

 

 

 

 

 

068

 

// TiffOutputSet class represents the Exif data to write.

 

 

 

 

 

069

 

//

 

 

 

 

 

070

 

// Usually, we want to update existing Exif metadata by

 

 

 

 

 

071

 

// changing

 

 

 

 

 

072

 

// the values of a few fields, or adding a field.

 

 

 

 

 

073

 

// In these cases, it is easiest to use getOutputSet() to

 

 

 

 

 

074

 

// start with a “copy” of the fields read from the image.

 

 

 

 

 

075

 

outputSet = exif.getOutputSet();

 

 

 

 

 

076

 

}

 

 

 

 

 

077

 

}

 

 

 

 

 

078

 

 

 

 

 

 

 

079

 

// if file does not contain any exif metadata, we create an empty

 

 

 

 

 

080

 

// set of exif metadata. Otherwise, we keep all of the other

 

 

 

 

 

081

 

// existing tags.

 

 

 

 

 

082

 

if (null == outputSet) {

 

 

 

 

 

083

 

outputSet = new TiffOutputSet();

 

 

 

 

 

084

 

}

 

 

 

 

 

085

 

 

 

 

 

 

 

086

 

{

 

 

 

 

 

087

 

// Example of how to add a field/tag to the output set.

 

 

 

 

 

088

 

//

 

 

 

 

 

089

 

// Note that you should first remove the field/tag if it already

 

 

 

 

 

090

 

// exists in this directory, or you may end up with duplicate

 

 

 

 

 

091

 

// tags. See above.

 

 

 

 

 

092

 

//

 

 

 

 

 

093

 

// Certain fields/tags are expected in certain Exif directories;

 

 

 

 

 

094

 

// Others can occur in more than one directory (and often have a

 

 

 

 

 

095

 

// different meaning in different directories).

 

 

 

 

 

096

 

//

 

 

 

 

 

097

 

// TagInfo constants often contain a description of what

 

 

 

 

 

098

 

// directories are associated with a given tag.

 

 

 

 

 

099

 

//

 

 

 

 

 

100

 

// see

 

 

 

 

 

101

 

// org.apache.commons.sanselan.formats.tiff.constants.AllTagConstants

 

 

 

 

 

102

 

//

 

 

 

 

 

103

 

final TiffOutputDirectory exifDirectory = outputSet

 

 

 

 

 

104

 

.getOrCreateExifDirectory();

 

 

 

 

 

105

 

// make sure to remove old value if present (this method will

 

 

 

 

 

106

 

// not fail if the tag does not exist).

 

 

 

 

 

107

 

exifDirectory

 

 

 

 

 

108

 

.removeField(ExifTagConstants.EXIF_TAG_APERTURE_VALUE);

 

 

 

 

 

109

 

exifDirectory.add(ExifTagConstants.EXIF_TAG_APERTURE_VALUE,

 

 

 

 

 

110

 

RationalNumber.factoryMethod(3, 10));

 

 

 

 

 

111

 

}

 

 

 

 

 

112

 

 

 

 

 

 

 

113

 

{

 

 

 

 

 

114

 

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

 

 

 

 

 

115

 

 

 

 

 

 

 

116

 

// New York City

 

 

 

 

 

117

 

final double longitude = -74.0; // 74 degrees W (in Degrees East)

 

 

 

 

 

118

 

final double latitude = 40 + 43 / 60.0; // 40 degrees N (in Degrees

 

 

 

 

 

119

 

// North)

 

 

 

 

 

120

 

 

 

 

 

 

 

121

 

outputSet.setGPSInDegrees(longitude, latitude);

 

 

 

 

 

122

 

}

 

 

 

 

 

123

 

 

 

 

 

 

 

124

 

// printTagValue(jpegMetadata, TiffConstants.TIFF_TAG_DATE_TIME);

 

 

 

 

 

125

 

 

 

 

 

 

 

126

 

os = new FileOutputStream(dst);

 

 

 

 

 

127

 

os = new BufferedOutputStream(os);

 

 

 

 

 

128

 

 

 

 

 

 

 

129

 

new ExifRewriter().updateExifMetadataLossless(jpegImageFile, os,

 

 

 

 

 

130

 

outputSet);

 

 

 

 

 

131

 

 

 

 

 

 

 

132

 

os.close();

 

 

 

 

 

133

 

os = null;

 

 

 

 

 

134

 

} finally {

 

 

 

 

 

135

 

if (os != null) {

 

 

 

 

 

136

 

try {

 

 

 

 

 

137

 

os.close();

 

 

 

 

 

138

 

} catch (final IOException e) {

 

 

 

 

 

139

 

 

 

 

 

 

 

140

 

}

 

 

 

 

 

141

 

}

 

 

 

 

 

142

 

}

 

 

 

 

 

143

 

}

 

 

 

 

 

144

 

 

 

 

 

 

 

145

 

/**

 

 

 

 

 

146

 

* This example illustrates how to remove a tag (if present) from EXIF

 

 

 

 

 

147

 

* metadata in a JPEG file.

 

 

 

 

 

148

 

*

 

 

 

 

 

149

 

* In this case, we remove the “aperture” tag from the EXIF metadata if

 

 

 

 

 

150

 

* present.

 

 

 

 

 

151

 

*

 

 

 

 

 

152

 

* @param jpegImageFile

 

 

 

 

 

153

 

* A source image file.

 

 

 

 

 

154

 

* @param dst

 

 

 

 

 

155

 

* The output file.

 

 

 

 

 

156

 


* @throws IOException

 

 

 

 

 

157

 

* @throws ImageReadException

 

 

 

 

 

158

 

* @throws ImageWriteException

 

 

 

 

 

159

 

*/

 

 

 

 

 

160

 

public void removeExifTag(final File jpegImageFile, final File dst) throws IOException,

 

 

 

 

 

161

 

ImageReadException, ImageWriteException {

 

 

 

 

 

162

 

OutputStream os = null;

 

 

 

 

 

163

 

try {

 

 

 

 

 

164

 

TiffOutputSet outputSet = null;

 

 

 

 

 

165

 

 

 

 

 

 

 

166

 

// note that metadata might be null if no metadata is found.

 

 

 

 

 

167

 

final IImageMetadata metadata = Imaging.getMetadata(jpegImageFile);

 

 

 

 

 

168

 

final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;

 

 

 

 

 

169

 

if (null != jpegMetadata) {

 

 

 

 

 

170

 

// note that exif might be null if no Exif metadata is found.

 

 

 

 

 

171

 

final TiffImageMetadata exif = jpegMetadata.getExif();

 

 

 

 

 

172

 

 

 

 

 

 

 

173

 

if (null != exif) {

 

 

 

 

 

174

 

// TiffImageMetadata class is immutable (read-only).

 

 

 

 

 

175

 

// TiffOutputSet class represents the Exif data to write.

 

 

 

 

 

176

 

//

 

 

 

 

 

177

 

// Usually, we want to update existing Exif metadata by

 

 

 

 

 

178

 

// changing

 

 

 

 

 

179

 

// the values of a few fields, or adding a field.

 

 

 

 

 

180

 

// In these cases, it is easiest to use getOutputSet() to

 

 

 

 

 

181

 

// start with a “copy” of the fields read from the image.

 

 

 

 

 

182

 

outputSet = exif.getOutputSet();

 

 

 

 

 

183

 

}

 

 

 

 

 

184

 

}

 

 

 

 

 

185

 

 

 

 

 

 

 

186

 

if (null == outputSet) {

 

 

 

 

 

187

 

// file does not contain any exif metadata. We don’t need to

 

 

 

 

 

188

 

// update the file; just copy it.

 

 

 

 

 

189

 

IoUtils.copyFileNio(jpegImageFile, dst);

 

 

 

 

 

190

 

return;

 

 

 

 

 

191

 

}

 

 

 

 

 

192

 

 

 

 

 

 

 

193

 

{

 

 

 

 

 

194

 

// Example of how to remove a single tag/field.

 

 

 

 

 

195

 

// There are two ways to do this.

 

 

 

 

 

196

 

 

 

 

 

 

 

197

 

// Option 1: brute force

 

 

 

 

 

198

 

// Note that this approach is crude: Exif data is organized in

 

 

 

 

 

199

 

// directories. The same tag/field may appear in more than one

 

 

 

 

 

200

 

// directory, and have different meanings in each.

 

 

 

 

 

201

 

outputSet.removeField(ExifTagConstants.EXIF_TAG_APERTURE_VALUE);

 

 

 

 

 

202

 

 

 

 

 

 

 

203

 

// Option 2: precision

 

 

 

 

 

204

 

// We know the exact directory the tag should appear in, in this

 

 

 

 

 

205

 

// case the “exif” directory.

 

 

 

 

 

206

 

// One complicating factor is that in some cases, manufacturers

 

 

 

 

 

207

 

// will place the same tag in different directories.

 

 

 

 

 

208

 

// To learn which directory a tag appears in, either refer to

 

 

 

 

 

209

 

// the constants in ExifTagConstants.java or go to Phil Harvey’s

 

 

 

 

 

210

 

// EXIF website.

 

 

 

 

 

211

 

final TiffOutputDirectory exifDirectory = outputSet

 

 

 

 

 

212

 

.getExifDirectory();

 

 

 

 

 

213

 

if (null != exifDirectory) {

 

 

 

 

 

214

 

exifDirectory

 

 

 

 

 

215

 

.removeField(ExifTagConstants.EXIF_TAG_APERTURE_VALUE);

 

 

 

 

 

216

 

}

 

 

 

 

 

217

 

}

 

 

 

 

 

218

 

 

 

 

 

 

 

219

 

os = new FileOutputStream(dst);

 

 

 

 

 

220

 

os = new BufferedOutputStream(os);

 

 

 

 

 

221

 

 

 

 

 

 

 

222

 

new ExifRewriter().updateExifMetadataLossless(jpegImageFile, os,

 

 

 

 

 

223

 

outputSet);

 

 

 

 

 

224

 

 

 

 

 

 

 

225

 

os.close();

 

 

 

 

 

226

 

os = null;

 

 

 

 

 

227

 

} finally {

 

 

 

 

 

228

 

if (os != null) {

 

 

 

 

 

229

 

try {

 

 

 

 

 

230

 

os.close();

 

 

 

 

 

231

 

} catch (final IOException e) {

 

 

 

 

 

232

 

 

 

 

 

 

 

233

 

}

 

 

 

 

 

234

 

}

 

 

 

 

 

235

 

}

 

 

 

 

 

236

 

}

 

 

 

 

 

237

 

 

 

 

 

 

 

238

 

/**

 

 

 

 

 

239

 

* This example illustrates how to set the GPS values in JPEG EXIF metadata.

 

 

 

 

 

240

 

*

 

 

 

 

 

241

 

* @param jpegImageFile

 

 

 

 

 

242

 

* A source image file.

 

 

 

 

 

243

 

* @param dst

 

 

 

 

 

244

 

* The output file.

 

 

 

 

 

245

 

* @throws IOException

 

 

 

 

 

246

 

* @throws ImageReadException

 

 

 

 

 

247

 

* @throws ImageWriteException

 

 

 

 

 

248

 

*/

 

 

 

 

 

249

 

public void setExifGPSTag(final File jpegImageFile, final File dst) throws IOException,

 

 

 

 

 

250

 

ImageReadException, ImageWriteException {

 

 

 

 

 

251

 

OutputStream os = null;

 

 

 

 

 

252

 

try {

 

 

 

 

 

253

 

TiffOutputSet outputSet = null;

 

 

 

 

 

254

 

 

 

 

 

 

 

255

 

// note that metadata might be null if no metadata is found.

 

 

 

 

 

256

 

final IImageMetadata metadata = Imaging.getMetadata(jpegImageFile);

 

 

 

 

 

257

 

final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;

 

 

 

 

 

258

 

if (null != jpegMetadata) {

 

 

 

 

 

259

 

// note that exif might be null if no Exif metadata is found.

 

 

 

 

 

260

 

final TiffImageMetadata exif = jpegMetadata.getExif();

 

 

 

 

 

261

 

 

 

 

 

 

 

262

 

if (null != exif) {

 

 

 

 

 

263

 

// TiffImageMetadata class is immutable (read-only).

 

 

 

 

 

264

 

// TiffOutputSet class represents the Exif data to write.

 

 

 

 

 

265

 

//

 

 

 

 

 

266

 

// Usually, we want to update existing Exif metadata by

 

 

 

 

 

267

 

// changing

 

 

 

 

 

268

 

// the values of a few fields, or adding a field.

 

 

 

 

 

269

 

// In these cases, it is easiest to use getOutputSet() to

 

 

 

 

 

270

 

// start with a “copy” of the fields read from the image.

 

 

 

 

 

271

 

outputSet = exif.getOutputSet();

 

 

 

 

 

272

 

}

 

 

 

 

 

273

 

}

 

 

 

 

 

274

 

 

 

 

 

 

 

275

 

// if file does not contain any exif metadata, we create an empty

 

 

 

 

 

276

 

// set of exif metadata. Otherwise, we keep all of the other

 

 

 

 

 

277

 

// existing tags.

 

 

 

 

 

278

 

if (null == outputSet) {

 

 

 

 

 

279

 

outputSet = new TiffOutputSet();

 

 

 

 

 

280

 

}

 

 

 

 

 

281

 

 

 

 

 

 

 

282

 

{

 

 

 

 

 

283

 

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

 

 

 

 

 

284

 

 

 

 

 

 

 

285

 

// New York City

 

 

 

 

 

286

 

final double longitude = -74.0; // 74 degrees W (in Degrees East)

 

 

 

 

 

287

 

final double latitude = 40 + 43 / 60.0; // 40 degrees N (in Degrees

 

 

 

 

 

288

 

// North)

 

 

 

 

 

289

 

 

 

 

 

 

 

290

 

outputSet.setGPSInDegrees(longitude, latitude);

 

 

 

 

 

291

 

}

 

 

 

 

 

292

 

 

 

 

 

 

 

293

 

os = new FileOutputStream(dst);

 

 

 

 

 

294

 

os = new BufferedOutputStream(os);

 

 

 

 

 

295

 

 

 

 

 

 

 

296

 

new ExifRewriter().updateExifMetadataLossless(jpegImageFile, os,

 

 

 

 

 

297

 

outputSet);

 

 

 

 

 

298

 

 

 

 

 

 

 

299

 

os.close();

 

 

 

 

 

300

 

os = null;

 

 

 

 

 

301

 

} finally {

 

 

 

 

 

302

 

if (os != null) {

 

 

 

 

 

303

 

try {

 

 

 

 

 

304

 

os.close();

 

 

 

 

 

305

 

} catch (final IOException e) {

 

 

 

 

 

306

 

 

 

 

 

 

 

307

 

}

 

 

 

 

 

308

 

}

 

 

 

 

 

309

 

}

 

 

 

 

 

310

 

}

 

 

 

 

 

311

 

 

 

 

 

 

 

312

 

}