第四十一篇: JAVA读取图像metadata信息

来源:互联网 发布:suse yum源配置 编辑:程序博客网 时间:2024/05/22 14:36

最近在做一个项目的时候需要要用的解析图像的拍摄时间,这些信息用图像查看工具基本都可以看到,之前有研究过MP3的文件格式,通过一些Tag来标记文件的一些信息,受此启发,猜测图像应该也有类似的机制。所以网上搜索了一下图像文件的存储格式,然后就查到了Exif规范,相机在拍照后按照Exif的相关规范,可以将拍摄时间、GPS等信息写入文件,我们按照规范格式将相关信息独取出来就好了,我上传了一份《Exif2.2》的官方文档,有兴趣可以下载查看。 
知道了存储的格式,开始动手写代码解析?如果我完全自己动手按照规范解析,还是挺麻烦的,而且我们不需要重复造轮子,网上已经有了相关的库可以实现该功能。

Imaging (previously called Sanselan)

之前写过一篇《Imaging (previously called Sanselan)读取图像信息》,简单的介绍了一下这个库以及用法,下面我们就烂看一下,如何读取metadata信息。

package test;import java.io.File;import java.io.IOException;import java.util.ArrayList;import org.apache.sanselan.ImageReadException;import org.apache.sanselan.Sanselan;import org.apache.sanselan.common.IImageMetadata;import org.apache.sanselan.formats.jpeg.JpegImageMetadata;import org.apache.sanselan.formats.tiff.TiffImageMetadata;import org.junit.Test;public class ImageMetaDataTest{   @Test   public void test() throws Exception   {      File imageFile = new File("C:\\Users\\admin\\Desktop\\mmexport1501076450193.jpg");      sanselan(imageFile);   }   public void sanselan(File file) throws ImageReadException, IOException   {      IImageMetadata metadata = Sanselan.getMetadata(file);      if (metadata == null)      {         return;      }      System.err.println("metadata items:");      ArrayList items = metadata.getItems();      for (Object item : items)      {         System.err.println(item);      }      System.err.println("GPS info:");      if (metadata instanceof JpegImageMetadata)      {         JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;         TiffImageMetadata exifMetadata = jpegMetadata.getExif();         if (null != exifMetadata)         {            TiffImageMetadata.GPSInfo gpsInfo = exifMetadata.getGPS();            if (null != gpsInfo)            {               double longitude = gpsInfo.getLongitudeAsDegreesEast();               double latitude = gpsInfo.getLatitudeAsDegreesNorth();               System.err.println("GPS Description: " + gpsInfo);               System.err.println("GPS Longitude (Degrees East): " + longitude);               System.err.println("GPS Latitude (Degrees North): " + latitude);            }         }      }   }}
  • 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
  • 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

在这段示例代码中,我们首先读取图像的MetaData信息和GPS数据,如果我们只需要读取拍摄时间的话,我们可以这样写:

public String getDateBySanselan(File file) throws ImageReadException, IOException{   IImageMetadata metadata = Sanselan.getMetadata(file);   if (metadata instanceof JpegImageMetadata)   {      JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;      TiffField field = jpegMetadata.findEXIFValue(TiffConstants.EXIF_TAG_DATE_TIME_ORIGINAL);      if (field != null)      {         return field.getValueDescription().replace("'", "");      }   }   return null;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

metadata-extractor

项目地址为:https://github.com/drewnoakes/metadata-extractor

package test;import java.io.File;import java.io.IOException;import java.util.ArrayList;import org.junit.Test;import com.drew.imaging.ImageMetadataReader;import com.drew.imaging.ImageProcessingException;import com.drew.metadata.Directory;import com.drew.metadata.Metadata;import com.drew.metadata.Tag;public class ImageMetaDataTest{   @Test   public void test() throws Exception   {      File imageFile = new File("C:\\Users\\admin\\Desktop\\mmexport1501076450193.jpg");      metadataExtractor(imageFile);   }   public void metadataExtractor(File file) throws ImageProcessingException, IOException   {      Metadata metadata = ImageMetadataReader.readMetadata(file);      for (Directory directory : metadata.getDirectories())      {         System.err.println(directory.getClass());         for (Tag tag : directory.getTags())         {            System.err.println(tag);         }      }   }}
  • 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
  • 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

同样的,上面一段代码也是打印图像的metadata信息,我个人感觉使用该包比Sanselan要方便一些,我们想要获得拍摄时间,只需要这样写:

public Date getDateByMetadataExtractor(File file) throws ImageProcessingException, IOException{   Metadata metadata = ImageMetadataReader.readMetadata(file);   ExifSubIFDDirectory directory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);   return directory.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
原创粉丝点击