从 Content:// 和 File:// URI 获取旋转信息

Getting rotation information from Content:// and File:// URIs

我在获取用户选择的图像然后确定是否有必要旋转它时遇到问题。我想我会很聪明,让我所有的处理都在 Uris 上进行,以便不知道图像的确切来源,但我所看到的确定旋转的方法似乎需要 Exif 信息,而这些信息不适用于内容: // Uri 的类型。

问题:如果我的句柄是一个 Uri,我如何确定图像是否需要旋转,而您不确定该图像来自哪里?

我这样做是为了获取图像:

        Intent intent = new Intent(Intent.ACTION_GET_CONTENT,
               android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            startActivityForResult(intent, INTENT_IMAGE_LOAD);

...并且在 onActivityResult() 中,我正在接收 Uri 以供稍后处理。

        Uri imageUri = data.getData();

        // if the imageUri needs rotation, then fix it here (I know how to fix it).
        // ... but I think I need to use Exif data which I can't get from Content:// URI
        // hmmmmmmmm


        doMyProcessingOnUri(context, imageUri);

显然 Android 7.0 改变了像这样使用 Intent 的某些方面,我认为发布的关于此的大部分帮助都与 pre-7.0 相关。

根据 Introducing the ExifInterface Support Library:

For apps that receive images from other apps with a content:// URI (such as those sent by apps that target API 24 or higher), ExifInterface now works directly off of an InputStream; this allows you to easily extract Exif information directly out of content:// URIs you receive without having to create a temporary file.

他们继续展示了如何提取旋转信息:

InputStream in = getContentResolver().openInputStream(uri);
ExifInterface exifInterface = new ExifInterface(in);
int rotation = 0;
int orientation = exifInterface.getAttributeInt(
    ExifInterface.TAG_ORIENTATION,
    ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
  case ExifInterface.ORIENTATION_ROTATE_90:
    rotation = 90;
    break;
  case ExifInterface.ORIENTATION_ROTATE_180:
    rotation = 180;
    break;
  case ExifInterface.ORIENTATION_ROTATE_270:
    rotation = 270;
    break;
}

您可以使用以下 Gradle 导入来包含 ExifInterface 支持库:

compile "com.android.support:exifinterface:26.0.1"