最近在公司干的打杂活,忙着忙那得,都是别人拍脑袋想的项目。恩,最近忙过什么的。

细分一下:
1.有google maps api的,比如根据一个地址,在google earth上定位,读取出该地的gps信息(经度,纬度);
2.有收发邮件的,自动读取邮件内容以及附件,自动更新到DB服务器上;
3.再就是我这次要说的,从图片上读取相应的exif,gps,iptc信息等。

代码我也懒得改了,大家要仔细看的话,都能看懂,我注释掉的部分其实是挺关键的,呵呵。

import java.io.File;
import java.math.BigDecimal;
import java.util.Iterator;

import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
import com.drew.metadata.exif.ExifDirectory;
import com.drew.metadata.exif.ExifReader;
import com.drew.metadata.exif.GpsDirectory;
import com.drew.metadata.iptc.IptcDirectory;
import com.drew.metadata.iptc.IptcReader;

/**
 * GPS情報付き画像ファイルから緯度経度を取得します
 *
 * @author www.webkkk.net
 */
public class ImgInfoReader {

 // 画像ファイル
 private String _strFile;

 // DMS形式緯度
 private String _strDmsLat;

 // DMS形式経度
 private String _strDmsLon;

 // DD形式緯度
 private String _strDdLat;

 // DD形式経度
 private String _strDdLon;

 /**
  * コンストラクター
  */
 public ImgInfoReader() {
 }

 /**
  * コンストラクター
  */
 public ImgInfoReader(String strFile) {
  this._strFile = strFile;
 }

 /**
  * 画像ファイルからGPS情報を取得します
  */
 private boolean getGpsInfo() {
  try {
   File file = new File(getStrFile());
   out("------" + file.getName() + "------");
   ExifReader er = new ExifReader(file);
   Metadata metadata = er.extract();

   Directory gpsDirectory = metadata.getDirectory(GpsDirectory.class);

   // --------------------- TEST -------------------//
   // {
   // out(String.valueOf(metadata.getDirectoryCount()));
   // Iterator itr = metadata.getDirectoryIterator();
   // while (itr.hasNext()) {
   // Directory directory = (Directory) itr.next();
   // out(directory.getClass().getName());
   // out("EXIF version:"
   // + directory
   // .getString(ExifDirectory.TAG_EXIF_VERSION));
   // String lat = directory
   // .getString(GpsDirectory.TAG_GPS_LATITUDE);
   // out(lat);
   // }
   // Directory itpcDirectory = metadata
   // .getDirectory(IptcDirectory.class);
   // out(itpcDirectory.getString(IptcDirectory.TAG_WRITER));
   // }
//   {
//    Iterator directories = metadata.getDirectoryIterator();
//    while (directories.hasNext()) {
//     Directory directory = (Directory) directories.next();
//     // iterate through tags and print to System.out
//     Iterator tags = directory.getTagIterator();
//     while (tags.hasNext()) {
//      Tag tag = (Tag) tags.next();
//      // use Tag.toString()
//      out(
////        tag.getTagType() + ":" + tag.getTagTypeHex() + ":"+
//        tag.getTagName() + ":" + tag.getDescription()
//        + ":" + tag.getDirectoryName());
//     }
//    }
//   }
//   {
//    IptcReader err = new IptcReader(file);
//    metadata = err.extract();
//    Iterator directories = metadata.getDirectoryIterator();
//    while (directories.hasNext()) {
//     Directory directory = (Directory) directories.next();
//     // iterate through tags and print to System.out
//     Iterator tags = directory.getTagIterator();
//     while (tags.hasNext()) {
//      Tag tag = (Tag) tags.next();
//      // use Tag.toString()
//      System.out.println(tag);
//     }
//    }
//   }
   // --------------------- TEST -------------------//

   String lat = gpsDirectory.getString(GpsDirectory.TAG_GPS_LATITUDE);
   String lon = gpsDirectory.getString(GpsDirectory.TAG_GPS_LONGITUDE);
   String lat_ref = gpsDirectory
     .getString(GpsDirectory.TAG_GPS_LATITUDE_REF);
   String lon_ref = gpsDirectory
     .getString(GpsDirectory.TAG_GPS_LONGITUDE_REF);
   String datum = gpsDirectory
     .getString(GpsDirectory.TAG_GPS_VERSION_ID);

   setDmsGpsInfo(lat, lon);
   setDdGpsInfo(lat_ref, getDDFromDMS(lat), lon_ref, getDDFromDMS(lon));
   out("----------------------------------------------");
   // ----------------- only for see ------------------------//
   // out(lat_ref);
   // out(lat);
   // out(getDDFromDMS(lat));
   // out(lon_ref);
   // out(lon);
   // out(getDDFromDMS(lon));
   // out(datum);
   // ----------------- only for see ------------------------//
   return true;
  } catch (Exception e) {
   // TODO JiangHai Auto-generated catch block
   e.printStackTrace();
   return false;
  }
 }

 /**
  * 画像ファイルを取得します
  *
  * @return 画像ファイルオブジェクト
  */
 private String getStrFile() {
  return _strFile;
 }

 /**
  * 画像ファイルオブジェクトをセットします
  *
  * @param strFile
  *            画像ファイル
  */
 public void setStrFile(String strFile) {
  this._strFile = strFile;
 }

 /**
  * DMS形式のGPS情報からDD形式のGPS情報を取得します
  *
  * @param strDms
  *            DMS形式のGPS情報
  * @return DD形式のGPS情報
  */
 private String getDDFromDMS(String strDms) {
  BigDecimal bidDd = new BigDecimal(0);
  BigDecimal bidPart = new BigDecimal(0);
  String[] strParts = strDms.split(" ");
  for (int i = 0, n = strParts.length; i < n; i++) {
   if (i == 0) {
    bidPart = getValue(strParts[i]);
   } else {
    bidPart = getValue(strParts[i]).divide(
      new BigDecimal(Math.pow(60, i)), 6,
      BigDecimal.ROUND_HALF_UP);
   }
   bidDd = bidDd.add(bidPart);
  }
  return String.valueOf(bidDd);
 }

 /**
  * 取得したデータからGPS情報を取得します
  *
  * @param strObj
  *            取得したデータ
  * @return GPS情報
  */
 private BigDecimal getValue(String strObj) {
  BigDecimal bidValue = new BigDecimal(0);
  String[] strParts = strObj.split("/");
  if (strParts.length == 0) {
   return bidValue;
  } else {
   return (new BigDecimal(strParts[0]).divide(new BigDecimal(
     strParts[1]), 6, BigDecimal.ROUND_HALF_UP));
  }
 }

 /**
  * DD形式のGPS情報を保存します
  *
  * @param strLatRef
  *            緯度フラグ
  * @param strLat
  *            緯度
  * @param strLonRef
  *            経度フラグ
  * @param strLon
  *            経度
  */
 private void setDdGpsInfo(String strLatRef, String strLat,
   String strLonRef, String strLon) {
  if ("N".equals(strLatRef)) {
   setStrDdLat(strLat);
  } else {
   setStrDdLat("-" + strLat);
  }

  if ("E".equals(strLonRef)) {
   setStrDdLon(strLon);
  } else {
   setStrDdLon("-" + strLon);
  }
 }

 /**
  * DMS形式のGPS情報を保存します
  *
  * @param strLat
  *            緯度
  * @param strLon
  *            経度
  */
 private void setDmsGpsInfo(String strLat, String strLon) {
  setStrDmsLat(strLat);
  setStrDmsLon(strLon);
 }

 /**
  * DMS形式の緯度情報を取得します
  *
  * @return 緯度情報
  */
 public String getStrDmsLat() {
  return _strDmsLat;
 }

 /**
  * DMS形式の経度情報を取得します
  *
  * @return 経度情報
  */
 public String getStrDmsLon() {
  return _strDmsLon;
 }

 /**
  * DD形式の緯度情報を取得します
  *
  * @return 緯度情報
  */
 public String getStrDdLat() {
  return _strDdLat;
 }

 /**
  * DD形式の経度情報を取得します
  *
  * @return 経度情報
  */
 public String getStrDdLon() {
  return _strDdLon;
 }

 /**
  * DMS形式の緯度情報を保存します
  *
  * @param strDmsLat
  *            緯度情報
  */
 private void setStrDmsLat(String strDmsLat) {
  this._strDmsLat = strDmsLat;
 }

 /**
  * DMS形式の経度情報を保存します
  *
  * @param strDmsLon
  *            経度情報
  */
 private void setStrDmsLon(String strDmsLon) {
  this._strDmsLon = strDmsLon;
 }

 /**
  * DD形式の緯度情報を保存します
  *
  * @param strDdLat
  *            緯度情報
  */
 private void setStrDdLat(String strDdLat) {
  this._strDdLat = strDdLat;
 }

 /**
  * DD形式の経度情報を保存します
  *
  * @param strDdLon
  *            経度情報
  */
 private void setStrDdLon(String strDdLon) {
  this._strDdLon = strDdLon;
 }

 /**
  * 距離の計算
  *
  * @param dblLonStart
  *            起点の経度
  * @param dblLatStart
  *            起点の緯度
  * @param dblLonEnd
  *            終点の経度
  * @param dblLatEnd
  *            終点の緯度
  * @return 距離
  */
 private double distanceByLnglat(double dblLonStart, double dblLatStart,
   double dblLonEnd, double dblLatEnd) {

  double radLat1 = dblLatStart * Math.PI / 180;
  double radLat2 = dblLatEnd * Math.PI / 180;
  double a = radLat1 - radLat2;
  double b = dblLonStart * Math.PI / 180 - dblLonEnd * Math.PI / 180;
  double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
    + Math.cos(radLat1) * Math.cos(radLat2)
    * Math.pow(Math.sin(b / 2), 2)));
  s = s * 6378137.0;// WGS84標準
  s = Math.round(s * 10000) / 10000;
  return s;
 }

 public void out(Object obj) {
  System.out.println(obj);
 }

 /**
  * @param args
  */
 public static void main(String args[]) {
  ImgInfoReader reader = new ImgInfoReader("c:\\img\\iptc.jpg");
  // ImgInfoReader reader = new ImgInfoReader("c:\\img\\o.jpg");
  if (reader.getGpsInfo()) {
   double s = reader.distanceByLnglat(Double.parseDouble(reader
     .getStrDdLon()), Double.parseDouble(reader.getStrDdLat()),
     Double.parseDouble("139.744123"), Double
       .parseDouble("35.630335"));
   System.out.println("distant:" + s);
  }
 }

}