Android EXIF GPS 坐标未正确提取(通过共享意图)
Android EXIF GPS coordinates not extracting correctly (via share intent)
我有一个应用程序,我试图在其中保存带有 gps 坐标 (EXIF) 的图像。当我通过图库将图像共享到我的应用程序时,图像按预期发送,但 gps 坐标返回 null,就好像它们不存在一样。
在我的应用程序中保存图像
保存代码如下:
...
// put gps location into image
ExifInterface exif = new ExifInterface(pictureFile.getCanonicalPath());
List<Double> latLon = getCurrentLatLon(); // this returns lat and lon doubles values
Log.d(null, "getPictureCallback lat " + latLon.get(0) + " lon " + latLon.get(1));
GPS gps = new GPS(); // class used to convert gps coordinates
exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, gps.convert(latLon.get(0)));
exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, gps.convert(latLon.get(0)));
exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, gps.convert(latLon.get(1)));
exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, gps.convert(latLon.get(1)));
exif.saveAttributes();
Log.i("getPictureCallback LATITUDE EXTRACTED", exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE));
Log.i("getPictureCallback LONGITUDE EXTRACTED", exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE));
// write to the file
FileOutputStream fos = new FileOutputStream(pictureFile);
// save the bitmap to a file compressed as a JPEG with 100% compression rate
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
上述代码的logcat:
05-10 14:55:12.161 8560-12142/com.example.fela E/JHEAD﹕ can't open '/storage/sdcard/Pictures/fela/IMG_20150510_145512.jpg'
05-10 14:55:12.161 8560-12142/com.example.fela D/﹕ getPictureCallback lat 13.003821666666665 lon 55.60497999999999
05-10 14:55:12.161 8560-12142/com.example.fela E/JHEAD﹕ can't open '/storage/sdcard/Pictures/fela/IMG_20150510_145512.jpg'
05-10 14:55:12.161 8560-12142/com.example.fela E/JHEAD﹕ Can't write back - didn't read all
05-10 14:55:12.161 8560-12142/com.example.fela I/getPictureCallback LATITUDE EXTRACTED﹕ 13/1,0/1,13757/1000,
05-10 14:55:12.161 8560-12142/com.example.fela I/getPictureCallback LONGITUDE EXTRACTED﹕ 55/1,36/1,17927/1000,
可以看到,坐标是这样写的:
getPictureCallback LATITUDE EXTRACTED﹕ 13/1,0/1,13757/1000
getPictureCallback LONGITUDE EXTRACTED﹕ 55/1,36/1,17927/1000
我推测它们现在保存在图像文件本身中。
通过图库分享到我的应用程序
下面是我分享保存到我的应用程序时的图像。
Intent intent = getActivity().getIntent();
String action = intent.getAction();
String type = intent.getType();
Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
Log.v(null, imageUri.getPath());
try {
ExifInterface exif = new ExifInterface(imageUri.getPath());
String lat = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
String lon = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
Log.v(null, "lat " + lat + " lon " + lon);
} catch (IOException e) {
e.printStackTrace();
}
LogCat:
05-10 14:47:25.274 8560-8560/com.example.fela V/﹕ /external/images/media/44
05-10 14:47:25.274 8560-8560/com.example.fela E/JHEAD﹕ can't open '/external/images/media/44'
05-10 14:47:25.274 8560-8560/com.example.fela V/﹕ lat null lon null
意图确实让位于我的应用程序中显示的图像,因此图像文件就在那里。
然而,您可以图像无法提取 gps 坐标,它们是空的。我不知道为什么它们是空的,因为我在保存时检查了它们。
当您写入 Bitmap.compress 中的 FileStream 时,您会覆盖该文件。这会覆盖标签。颠倒这些操作的顺序。
这一直是我如何读取意图图像的 uri 路径的问题。正确答案在上面的link
String imagePath = getRealPathFromURI(imageUri);
ExifInterface exif = new ExifInterface(imagePath);
String lat = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
String lon = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
以及让它发挥作用的方法:
private String getRealPathFromURI(Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
CursorLoader loader = new CursorLoader(getActivity(), contentUri, proj, null, null, null);
Cursor cursor = loader.loadInBackground();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
同样如Gabe Sechan
所述,它必须在bitmap.compress
之后,否则将被覆盖。
我有一个应用程序,我试图在其中保存带有 gps 坐标 (EXIF) 的图像。当我通过图库将图像共享到我的应用程序时,图像按预期发送,但 gps 坐标返回 null,就好像它们不存在一样。
在我的应用程序中保存图像
保存代码如下:
...
// put gps location into image
ExifInterface exif = new ExifInterface(pictureFile.getCanonicalPath());
List<Double> latLon = getCurrentLatLon(); // this returns lat and lon doubles values
Log.d(null, "getPictureCallback lat " + latLon.get(0) + " lon " + latLon.get(1));
GPS gps = new GPS(); // class used to convert gps coordinates
exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, gps.convert(latLon.get(0)));
exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, gps.convert(latLon.get(0)));
exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, gps.convert(latLon.get(1)));
exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, gps.convert(latLon.get(1)));
exif.saveAttributes();
Log.i("getPictureCallback LATITUDE EXTRACTED", exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE));
Log.i("getPictureCallback LONGITUDE EXTRACTED", exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE));
// write to the file
FileOutputStream fos = new FileOutputStream(pictureFile);
// save the bitmap to a file compressed as a JPEG with 100% compression rate
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
上述代码的logcat:
05-10 14:55:12.161 8560-12142/com.example.fela E/JHEAD﹕ can't open '/storage/sdcard/Pictures/fela/IMG_20150510_145512.jpg'
05-10 14:55:12.161 8560-12142/com.example.fela D/﹕ getPictureCallback lat 13.003821666666665 lon 55.60497999999999
05-10 14:55:12.161 8560-12142/com.example.fela E/JHEAD﹕ can't open '/storage/sdcard/Pictures/fela/IMG_20150510_145512.jpg'
05-10 14:55:12.161 8560-12142/com.example.fela E/JHEAD﹕ Can't write back - didn't read all
05-10 14:55:12.161 8560-12142/com.example.fela I/getPictureCallback LATITUDE EXTRACTED﹕ 13/1,0/1,13757/1000,
05-10 14:55:12.161 8560-12142/com.example.fela I/getPictureCallback LONGITUDE EXTRACTED﹕ 55/1,36/1,17927/1000,
可以看到,坐标是这样写的:
getPictureCallback LATITUDE EXTRACTED﹕ 13/1,0/1,13757/1000
getPictureCallback LONGITUDE EXTRACTED﹕ 55/1,36/1,17927/1000
我推测它们现在保存在图像文件本身中。
通过图库分享到我的应用程序
下面是我分享保存到我的应用程序时的图像。
Intent intent = getActivity().getIntent();
String action = intent.getAction();
String type = intent.getType();
Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
Log.v(null, imageUri.getPath());
try {
ExifInterface exif = new ExifInterface(imageUri.getPath());
String lat = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
String lon = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
Log.v(null, "lat " + lat + " lon " + lon);
} catch (IOException e) {
e.printStackTrace();
}
LogCat:
05-10 14:47:25.274 8560-8560/com.example.fela V/﹕ /external/images/media/44
05-10 14:47:25.274 8560-8560/com.example.fela E/JHEAD﹕ can't open '/external/images/media/44'
05-10 14:47:25.274 8560-8560/com.example.fela V/﹕ lat null lon null
意图确实让位于我的应用程序中显示的图像,因此图像文件就在那里。
然而,您可以图像无法提取 gps 坐标,它们是空的。我不知道为什么它们是空的,因为我在保存时检查了它们。
当您写入 Bitmap.compress 中的 FileStream 时,您会覆盖该文件。这会覆盖标签。颠倒这些操作的顺序。
这一直是我如何读取意图图像的 uri 路径的问题。正确答案在上面的link
String imagePath = getRealPathFromURI(imageUri);
ExifInterface exif = new ExifInterface(imagePath);
String lat = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
String lon = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
以及让它发挥作用的方法:
private String getRealPathFromURI(Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
CursorLoader loader = new CursorLoader(getActivity(), contentUri, proj, null, null, null);
Cursor cursor = loader.loadInBackground();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
同样如Gabe Sechan
所述,它必须在bitmap.compress
之后,否则将被覆盖。