Java抽取照片的元数据信息

清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>

首先简单看看什么是元数据(Metadata)。元数据是数据的数据或者叫做用来描述数据的数据。这句解释也许很抽象,我们看个他的用途。我们可以把元数据简单的理解成,最小的数据单位。元数据可以为数据说明其元素或属性或其结构以及相关数据。

最广泛的其中一个应用就是每张相片中都包含了一个Exif信息,它就是一种用来描述数码图片的元数据。EXIF是exchangeable Image File的缩写,这是一种专门为数码相机照片设定的格式。这种格式可以用来记录数字照片的属性信息,例如相机的品牌及型号、相片的拍摄时间、拍摄时所设置 的光圈大小、快门速度、ISO等等信息。除此之外它还能够记录拍摄数据,以及照片格式化方式。

根据Exif2.1标准,元数据信息包含:

Image Description 图像描述、来源. 指生成图像的工具
Artist 作者 有些相机可以输入使用者的名字
Make 生产者 指产品生产厂家
Model 型号 指设备型号
Orientation方向 有的相机支持,有的不支持
XResolution/YResolution X/Y方向分辨率 本栏目已有专门条目解释此问题。
ResolutionUnit分辨率单位 一般为PPI
Software软件 显示固件Firmware版本
DateTime日期和时间
YCbCrPositioning 色相定位
ExifOffsetExif信息位置,定义Exif在信息在文件中的写入,有些软件不显示。
ExposureTime 曝光时间 即快门速度
FNumber光圈系数
ExposureProgram曝光程序 指程序式自动曝光的设置,各相机不同,可能是Sutter Priority(快门优先)、Aperture Priority(快门优先)等等。
ISO speed ratings感光度
ExifVersionExif版本
DateTimeOriginal创建时间
DateTimeDigitized数字化时间
ComponentsConfiguration图像构造(多指色彩组合方案)
CompressedBitsPerPixel(BPP)压缩时每像素色彩位 指压缩程度
ExposureBiasValue曝光补偿。
MaxApertureValue最大光圈
MeteringMode测光方式, 平均式测光、中央重点测光、点测光等。
Lightsource光源 指白平衡设置
Flash是否使用闪光灯。
FocalLength焦距,一般显示镜头物理焦距,有些软件可以定义一个系数,从而显示相当于35mm相机的焦距 MakerNote(User Comment)作者标记、说明、记录
FlashPixVersionFlashPix版本 (个别机型支持)
ColorSpace色域、色彩空间
ExifImageWidth(Pixel X Dimension)图像宽度 指横向像素数
ExifImageLength(Pixel Y Dimension)图像高度 指纵向像素数
Interoperability IFD通用性扩展项定义指针 和TIFF文件相关,具体含义不详
FileSource源文件 Compression压缩比。

元数据最大的好处是,它使信息的描述和分类可以实现格式化,从而为机器处理创造了可能。那我们如何拿到这些信息呢?这里介绍Drew Noakes写的metadata-extractor。目前最新的版本是V2.5.0 RC2。我发现这个版本与之前的V2.3.1还是做了一些更改,包括API的实现。关于V2.3.1版本的元数据提取可以参考我之前写的文章:Java读取图片EXIF信息

接下来看看如何使用Metadata-extractor类库来读取图片中的元数据。这样做的一个应用就是你可以给你的图片按照某种格式分类的,用过Google picasa中就有这种功能。

首先需要导入metadata-extractor-2.5.0-RC2.jar,如果你是直接在console编译的话,那么编译语 句:javac -d. -classpath metadata-extractor-2.5.0-RC2.jar MetaDataReader.java 下面是MetaDataReader.java的源码:

import java.io.File;
import java.util.Collection;
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.ExifIFD0Directory;

/**
 * 测试用于读取图片的EXIF信息
 * @author Leyond
 * @Blog   codecho.com
 */
public class MetaDataReader {
     public static void main(String[] args) throws Exception {
         File jpegFile = new File("src/Nikon E990.jpg");
         Metadata metadata = JpegMetadataReader.readMetadata(jpegFile);
         Directory exif = metadata.getDirectory(ExifIFD0Directory.class);
         Collection<Tag> tags = exif.getTags();
         Iterator<Tag> iter = tags.iterator();
         //逐个遍历每个Tag
         while(iter.hasNext())
         {
          Tag tag = (Tag)iter.next();
          System.out.println(tag);
         }
         //检查是否Tag中包含了图片属性-摘要中的作者 (xp)
         if(exif.containsTag(ExifIFD0Directory.TAG_WIN_AUTHOR)){
             System.out.println("Pic author is "+exif.getDescription(ExifIFD0Directory.TAG_WIN_AUTHOR));
         }
       //检查是否Tag中包含了图片属性-摘要中的标题 (xp)
         if(exif.containsTag(ExifIFD0Directory.TAG_WIN_TITLE)){
             System.out.println("Pic title is "+exif.getDescription(ExifIFD0Directory.TAG_WIN_TITLE));
           }
       //检查是否Tag中包含了图片属性-摘要中的主题 (xp)
           if(exif.containsTag(ExifIFD0Directory.TAG_WIN_SUBJECT )){
         System.out.println("Pic subject is "+exif.getDescription(ExifIFD0Directory.TAG_WIN_SUBJECT ));
         }
     }
}

执行结果:
[Exif IFD0] Make – NIKON
[Exif IFD0] Model – E990
[Exif IFD0] Orientation – Top, left side (Horizontal / normal)
[Exif IFD0] X Resolution – 300 dots per inch
[Exif IFD0] Y Resolution – 300 dots per inch
[Exif IFD0] Resolution Unit – Inch
[Exif IFD0] Software – E990v1.1
[Exif IFD0] Date/Time – 2000:12:30 10:18:16
[Exif IFD0] YCbCr Positioning – Datum point
[Exif IFD0] Windows XP Title – Codecho.com
[Exif IFD0] Windows XP Author – Leyond
[Exif IFD0] Windows XP Subject – Test
Pic author is Leyond
Pic title is Codecho.com
Pic subject is Test

其中后面三项分别是图片属性-摘要中的标题、主题、作者信息。当然你还可以读取关键字(TAG_WIN_KEYWORDS)等信息。具体参考: Javadoc