EXIF是一种图象文件格式,它的数据存储与JPEG格式是完全相同的。实际上EXIF格式就是在JPEG格式头部插入了数码照片的信息,包括拍摄时的光圈、快门、白平衡、ISO、焦距、日期时间等各种和拍摄条件以及相机品牌、型号、色彩编码、拍摄时录制的声音以及全球定位系统(GPS)、缩略图等。
EXIF是Exchangeable Image File的缩写,这是一种专门为数码相机照片设定的格式。这种格式可以用来记录数字照片的属性信息,例如相机的品牌及型号、相片的拍摄时间、拍摄时所设置的光圈大小、快门速度、ISO等等信息。除此之外它还能够记录拍摄数据,以及照片格式化方式,这样就可以输出到兼容EXIF格式的外设上,例如照片打印机等。
目前最常见的支持EXIF信息的图片格式是JPG,很多的图像工具都可以直接显示图片的EXIF信息,包括现在的一些著名的相册网站也提供页面用于显示照片的EXIF信息。本文主要介绍Java语言如何读取图像的EXIF信息,包括如何根据EXIF信息对图像进行调整以适合用户浏览。需要注意的是,并不是每个JPG图像文件都包含有EXIF信息
目前最简单易用的EXIF信息处理的Java包是Drew Noakes写的metadata-extractor,该项目最新的版本是2.3.0,支持EXIF 2.2版本。你可以直接从http://www.drewnoakes.com/code/exif/ 下载该项目的最新版本包括其源码。
下面这个示例是把图片的所有的EXIF信息全部打印出来:
import java.io.File;
import java.util.Iterator;
import com.drew.imaging.jpeg.JpegMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
import com.drew.metadata.exif.ExifDirectory;
/**
* 测试用于读取图片的EXIF信息
* @author Winter Lau
*/
public class ExifTester {
public static void main(String[] args) throws Exception {
File jpegFile = new File("D:\\我的文档\\我的相册\\DSCF1749.JPG");
Metadata metadata = JpegMetadataReader.readMetadata(jpegFile);
Directory exif = metadata.getDirectory(ExifDirectory.class);
Iterator tags = exif.getTagIterator();
while (tags.hasNext()) {
Tag tag = (Tag)tags.next();
System.out.println(tag);
}
}
}
下面这个示例是读取相机的型号:
Metadata metadata = JpegMetadataReader.readMetadata(jpegFile);
Directory exif = metadata.getDirectory(ExifDirectory.class);
String model = exif.getString(ExifDirectory.TAG_MODEL);
下面这个示例是读取图片方向:
Metadata metadata = JpegMetadataReader.readMetadata(jpegFile);
Directory exif = metadata.getDirectory(ExifDirectory.class);
String direction = exif.getString(ExifDirectory.TAG_ORIENTATION);
获得了方向还要知道方向对应的图片显示方向,我们在拍照的时候经常会根据场景的不同来选择相机的方向,例如拍摄一颗高树,我们会把相机竖着拍摄,使景物刚好适合整个取景框,但是这样得到的图片如果用普通的图片浏览器看便是倒着的,需要调整角度才能得到一个正常的图像,
public String getOrientationDescription() throws MetadataException{
if (!_directory.containsTag(ExifDirectory.TAG_ORIENTATION)) return null;
int orientation = _directory.getInt(ExifDirectory.TAG_ORIENTATION);
switch (orientation) {
case 1: return "Top, left side (Horizontal / normal)";
case 2: return "Top, right side (Mirror horizontal)";
case 3: return "Bottom, right side (Rotate 180)";
case 4: return "Bottom, left side (Mirror vertical)";
case 5: return "Left side, top (Mirror horizontal and rotate 270 CW)";
case 6: return "Right side, top (Rotate 90 CW)";
case 7: return "Right side, bottom (Mirror horizontal and rotate 90 CW)";
case 8: return "Left side, bottom (Rotate 270 CW)";
default: return String.valueOf(orientation);
}