使用Uri获取Exif数据

时间:2016-06-10 08:52:00

标签: android bitmap uri exif

我想获取我从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数据一起保存,以便我可以将它发送到服务器。

1 个答案:

答案 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;
}