事实证明,解决最初的问题变成了一系列新问题。这是供更多读者阅读的完整教程。
首先,作为@CommonsWare pointed in his answer,我们必须使用EXIF方向标签手动处理方向。为了避免错误/安全缺陷android.media.ExifInterface 以及第 3 方依赖项,最好的选择似乎是一个新的 com.android.support:exifinterface 库,我们将其添加到 build.gradle 为:
dependencies {
compile 'com.android.support:exifinterface:26.0.0'
}
但是对我来说,它导致了 Gradle 同步错误,原因是在 Google 存储库中找不到这个特定的最新版本的库,尽管根据Support Library Packages 页面,这个版本是最新的。
经过一个小时的试用,我发现 jcenter() 存储库还不够,通过添加 Google Maven 存储库修复了 Gradle 同步:
allprojects {
repositories {
jcenter()
maven {
url 'https://maven.google.com'
// Alternative URL is 'https://dl.google.com/dl/android/maven2/'
}
}
}
好的,现在我们可以使用android.support.media.ExifInterface了。
下一个令人失望的是,存储在 EXIF 标签中的宽度和高度也不尊重方向,即对于以纵向模式拍摄的图像,您获得的宽度和高度与使用 BitmapFactory.decodeFile() 创建的 Bitmap 返回的宽度和高度相同。所以唯一的方法是手动查看 EXIF ExifInterface.TAG_ORIENTATION 标签,如果它说图像旋转了 90 度或 270 度 - 交换宽度和高度:
ExifInterface exif = new ExifInterface(fileNameFull);
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
BitmapFactory.Options optsForBounds = new BitmapFactory.Options();
optsForBounds.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fileName, optsForBounds);
int width = optsForBounds.outWidth, height = optsForBounds.outHeight;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90 || orientation == ExifInterface.ORIENTATION_ROTATE_270)
{
int temp = width;
//noinspection SuspiciousNameCombination
width = height;
height = temp;
}
我不确定这种方法和代码是否涵盖 100% 的情况,因此如果您在各种设备/图像源中遇到任何问题 - 请随时发表评论。
总的来说,处理 EXIF 似乎不是一个愉快的经历。即使是大公司对 EXIF 标准的实施似乎对细微差别的处理方式也大相径庭。见详细分析here。