我想获取我从Android图库或Google相似类似应用中挑选的图片的Exif
数据。以下是我用于从Uri
获取图像文件的方法:
public static String getActualPathFromUri(@NonNull Context context, @NonNull Uri selectedImageUri) {
Bitmap bitmap = null;
try {
bitmap = getBitmapFromUri(context, selectedImageUri);
} catch (IOException e) {
e.printStackTrace();
}
if (bitmap == null) {
return null;
}
File imageFileFolder = new File(context.getCacheDir(), "example");
if (!imageFileFolder.exists()) {
imageFileFolder.mkdir();
}
FileOutputStream out = null;
File imageFileName = new File(imageFileFolder, "example-" + System.currentTimeMillis() + ".jpg");
try {
out = new FileOutputStream(imageFileName);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (IOException e) {
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return imageFileName.getAbsolutePath();
}
private static Bitmap getBitmapFromUri(@NonNull Context context, @NonNull Uri uri) throws IOException {
ParcelFileDescriptor parcelFileDescriptor =
context.getContentResolver().openFileDescriptor(uri, "r");
assert parcelFileDescriptor != null;
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
}
我从Bitmap
选择Uri
而不是获取系统文件名的原因是因为该方法针对不同版本的Android进行了分段。此外,在Google相册等应用中,某些照片会直接从服务器显示,而不是存储在设备上,因此无法获取文件名。即使我获得了文件名,但在我的应用程序中尝试使用时,我会得到Security Exception
。
这种方法的问题是,当我得到Bitmap
时,我无法获得Exif
数据。但我需要Exif
数据并将其附加到我保存在cache
文件夹中的文件中,这样当我将图像上传到服务器时,它会将图像与Exif
一起获取,以便它可以做一些进一步的处理。原因是,我需要将其保存为文件或至少获取文件,如果它已经存在于系统中,那是因为Retrofit
需要一个File
对象,然后转换为TypedFile
并使用Multipart
请求发送到服务器。
那么,我如何准确地从任何类型的图像Uri(本地或服务器)获取Exif
信息,然后将图像与其Exif
数据一起保存,以便我可以将它发送到服务器。
答案 0 :(得分:1)
以下代码可以帮助您
String path = FileUtility.getRealPathFromURI(context, Uri.parse(bitmapUri.getPath());
ExifInterface exif = new ExifInterface(path);
rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL);
FileUtility.java
public static String getRealPathFromURI(Context context, Uri contentUri) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
return getPathForV19AndUp(context, contentUri);
} else {
return getPathForPreV19(context, contentUri);
}
}
public static String getPathForPreV19(Context context, Uri contentUri) {
String res = null;
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
if(cursor.moveToFirst()){;
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
res = cursor.getString(column_index);
}
cursor.close();
return res;
}
@TargetApi(Build.VERSION_CODES.KITKAT)
public static String getPathForV19AndUp(Context context, Uri contentUri) {
String wholeID = DocumentsContract.getDocumentId(contentUri);
// Split at colon, use second item in the array
String id = wholeID.split(":")[1];
String[] column = { MediaStore.Images.Media.DATA };
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = context.getContentResolver().
query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]{ id }, null);
String filePath = "";
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
return filePath;
}