最近在公司干的打杂活,忙着忙那得,都是别人拍脑袋想的项目。恩,最近忙过什么的。
细分一下:
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);
}
}
}