Android中通过Exifinterface读取图片地理位置信息
2017-09-21 15:57
881 查看
效果图:
Exif 文件实际是JPEG文件的一种,遵从JPEG标准,只是在文件头信息中增加了有关拍摄信息的内容和索引图。所以你可以使用任何支持JPEG格式的图像工具软件观看 Exif 文件,但图像一旦被修改,Exif 信息可能会永久丢失,故编辑 Exif 必须使用专门的软件。
目前能够正确读取并识别的厂商注释等信息的Exif 查看/编辑软件比较少:主要有ExifTool、MagicEXIF等。
相关Tag:
TAG_DATETIME时间日期
TAG_FLASH闪光灯
TAG_GPS_LATITUDE纬度
TAG_GPS_LATITUDE_REF纬度参考
TAG_GPS_LONGITUDE经度
TAG_GPS_LONGITUDE_REF经度参考
TAG_IMAGE_LENGTH图片长
TAG_IMAGE_WIDTH图片宽
TAG_MAKE设备制造商
TAG_MODEL设备型号
TAG_ORIENTATION方向
TAG_WHITE_BALANCE白平衡
2
3
Exifinterface
定位(获取当前位置)有两种方法:
1、通过LocationManager,其实就是通过GPS获取
但是这样貌似不行,可能由于google被墙或者这个方法的权限问题,导致这个location为null
2、通过高德地图定位SDK的AMapLocationClient
初始化定位、设置定位监听器后并启动定位mLocationClient.startLocation()后确实可以拿到当前经纬度,但在我的demo里,试了下太耗时(还没深原因),但是如果在一个完整的项目里,可以这样做。
1、在拍照的照片识别中,只有努比亚不可以读取图片的经纬度信息,但是可以读取机型等信息。
2、在选取本地图库的照片(由本机相机拍照所得)识别中,同上。
3、在选取本地图库的图片(由非本机相机所得,比如网络下载、裁剪等渠道而来)识别中,都无法读取相关信息。
4、以上3条可以总结为1条,只能识别那些带有exif信息的图片
2、声明:demo是一个android module,可以直接复制到现有的project下;测试时记得开启手机的GPS权限。
3、要修改的地方:打包签名的keystore需要换成自己的;高德地图key需要自己根据keystore重新申请。
一、了解Exif
EXIF(Exchangeable Image File)是“可交换图像文件”的缩写,是一种图像文件格式,它的数据存储与JPEG格式是完全相同的,当中包含了专门为数码相机的照片而定制的元数据,可以记录数码照片拍摄时的光圈、快门、白平衡、ISO、焦距、日期时间等各种和拍摄条件以及相机品牌、型号、色彩编码、拍摄时录制的声音以及GPS全球定位系统数据、缩略图等。Exif 文件实际是JPEG文件的一种,遵从JPEG标准,只是在文件头信息中增加了有关拍摄信息的内容和索引图。所以你可以使用任何支持JPEG格式的图像工具软件观看 Exif 文件,但图像一旦被修改,Exif 信息可能会永久丢失,故编辑 Exif 必须使用专门的软件。
目前能够正确读取并识别的厂商注释等信息的Exif 查看/编辑软件比较少:主要有ExifTool、MagicEXIF等。
二、学习ExifInterface
Android2.0后新增的一个类相关Tag:
TAG_DATETIME时间日期
TAG_FLASH闪光灯
TAG_GPS_LATITUDE纬度
TAG_GPS_LATITUDE_REF纬度参考
TAG_GPS_LONGITUDE经度
TAG_GPS_LONGITUDE_REF经度参考
TAG_IMAGE_LENGTH图片长
TAG_IMAGE_WIDTH图片宽
TAG_MAKE设备制造商
TAG_MODEL设备型号
TAG_ORIENTATION方向
TAG_WHITE_BALANCE白平衡
/** * This is a class for reading and writing Exif tags in a JPEG file. */1
2
3
Exifinterface
三、简单应用
根据选择的本地图片的exif信息,读取到地理位置的经纬度,然后使用高德地图反地理编码解析出地理位置名称,如果图片中没有包含或者无法包含经纬度信息,那么就在用户发起拍照请求时通过高德定位SDK拿到相关信息。以前没注意到有这么个类,先记录下,待会抽空来完善优化下流程和代码。定位(获取当前位置)有两种方法:
1、通过LocationManager,其实就是通过GPS获取
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);1
但是这样貌似不行,可能由于google被墙或者这个方法的权限问题,导致这个location为null
2、通过高德地图定位SDK的AMapLocationClient
//声明定位回调监听器 public AMapLocationListener mLocationListener = new AMapLocationListener() { @Override public void onLocationChanged(AMapLocation amapLocation) { if (amapLocation != null) { if (amapLocation.getErrorCode() == 0) { //定位成功回调信息,设置相关消息 amapLocation.getLocationType();//获取当前定位结果来源,如网络定位结果,详见定位类型表 currentLat = amapLocation.getLatitude();//获取纬度 currentLon = amapLocation.getLongitude();//获取经度 } } } };
初始化定位、设置定位监听器后并启动定位mLocationClient.startLocation()后确实可以拿到当前经纬度,但在我的demo里,试了下太耗时(还没深原因),但是如果在一个完整的项目里,可以这样做。
public LatLng getPhotoLocation(String imagePath) { LogUtil.i("TAG", "getPhotoLocation==" + imagePath); LatLng latLng = null; try { ExifInterface exifInterface = new ExifInterface(imagePath); String datetime = exifInterface.getAttribute(ExifInterface.TAG_DATETIME);// 拍摄时间 String deviceName = exifInterface.getAttribute(ExifInterface.TAG_MAKE);// 设备品牌 String deviceModel = exifInterface.getAttribute(ExifInterface.TAG_MODEL); // 设备型号 String latValue = exifInterface.getAttribute(ExifInterface.TAG_GPS_LATITUDE); String lngValue = exifInterface.getAttribute(ExifInterface.TAG_GPS_LONGITUDE); String latRef = exifInterface.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF); String lngRef = exifInterface.getAttribute (ExifInterface.TAG_GPS_LONGITUDE_REF); if (latValue != null && latRef != null && lngValue != null && lngRef != null) { try { output1 = convertRationalLatLonToFloat(latValue, latRef); output2 = convertRationalLatLonToFloat(lngValue, lngRef); } catch (IllegalArgumentException e) { e.printStackTrace(); } } Toast.makeText(TestActivity.this, deviceName + ":" + deviceModel, Toast.LENGTH_LONG).show(); } catch (Exception e) { e.printStackTrace(); } Toast.makeText(TestActivity.this, output1 + ";" + output1 , Toast.LENGTH_LONG).show(); latLng = new LatLng(output1 , output1 ); return latLng; } private static float convertRationalLatLonToFloat( String rationalString, String ref) { String[] parts = rationalString.split(","); String[] pair; pair = parts[0].split("/"); double degrees = Double.parseDouble(pair[0].trim()) / Double.parseDouble(pair[1].trim()); pair = parts[1].split("/"); double minutes = Double.parseDouble(pair[0].trim()) / Double.parseDouble(pair[1].trim()); pair = parts[2].split("/"); double seconds = Double.parseDouble(pair[0].trim()) / Double.parseDouble(pair[1].trim()); double result = degrees + (minutes / 60.0) + (seconds / 3600.0); if ((ref.equals("S") || ref.equals("W"))) { return (float) -result; } return (float) result; }
四、总结
经过简单测试了魅蓝note2、努比亚、华为P6三款机型,得出结论:1、在拍照的照片识别中,只有努比亚不可以读取图片的经纬度信息,但是可以读取机型等信息。
2、在选取本地图库的照片(由本机相机拍照所得)识别中,同上。
3、在选取本地图库的图片(由非本机相机所得,比如网络下载、裁剪等渠道而来)识别中,都无法读取相关信息。
4、以上3条可以总结为1条,只能识别那些带有exif信息的图片
五、样例下载
1、下载地址点这里,代码很少,仅供参考。2、声明:demo是一个android module,可以直接复制到现有的project下;测试时记得开启手机的GPS权限。
3、要修改的地方:打包签名的keystore需要换成自己的;高德地图key需要自己根据keystore重新申请。
相关文章推荐
- Android中通过Exifinterface读取图片地理位置信息
- Android中通过Exifinterface读取图片地理位置信息
- Android ExifInterface 图片信息 读取时中文乱码解决方案
- 通过ExifInterface 读取图片信息
- 在Android下通过ExifInterface类操作图片的Exif信息
- 通过ExifInterface 读取图片信息
- [置顶] Android中通过Exif-ExifInterface获取图片的相关信息,并且在图片上添加获取到的信息将图片展示出来
- 通过ExifInterface 读取图片信息
- 在Android下通过ExifInterface类操作图片的Exif信息
- Android将地理位置存储到图片扩展信息EXIF
- Android多媒体- ExifInterface读取图片相关信息
- Android读取图片当中的信息exif
- Android 通过经纬度获取地理位置信息
- android 读取图片 EXIF信息
- iOS 关于图片地理位置隐私信息的分析和读取
- iOS 关于图片地理位置隐私信息的分析和读取
- Android通过百度地图API用Service和Alarm在后台定时获取地理位置信息
- Android 端读取图片exif信息,并对其进行修改
- Android通过百度地图API用Service和Alarm在后台定时获取地理位置信息
- Android通过百度地图API用Service和Alarm在后台定时获取地理位置信息