39

我环顾四周,但似乎没有一个可靠的答案/解决方案来解决这个非常令人恼火的问题。

我以纵向拍摄照片,当我点击保存/丢弃时,按钮的方向也正确。问题是当我稍后检索图像时,它是横向的(图片已逆时针旋转 90 度)

我不想强迫用户在某个方向使用相机。

有没有办法检测照片是否是在纵向模式下拍摄的,然后解码位图并以正确的方式向上翻转?

4

2 回答 2

88

始终按照相机内置在设备中的方向拍摄照片。要正确旋转图像,您必须读取存储在图片中的方向信息(EXIF 元数据)。那里存储了拍摄图像时设备的方向。

下面是一些读取 EXIF 数据并相应地旋转图像的代码: file是图像文件的名称。

BitmapFactory.Options bounds = new BitmapFactory.Options();
bounds.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file, bounds);

BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFile(file, opts);
ExifInterface exif = new ExifInterface(file);
String orientString = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
int orientation = orientString != null ? Integer.parseInt(orientString) :  ExifInterface.ORIENTATION_NORMAL;

int rotationAngle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) rotationAngle = 90;
if (orientation == ExifInterface.ORIENTATION_ROTATE_180) rotationAngle = 180;
if (orientation == ExifInterface.ORIENTATION_ROTATE_270) rotationAngle = 270;

Matrix matrix = new Matrix();
matrix.setRotate(rotationAngle, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
Bitmap rotatedBitmap = Bitmap.createBitmap(bm, 0, 0, bounds.outWidth, bounds.outHeight, matrix, true);

更新 2017-01-16

随着 25.1.0 支持库的发布,引入了 ExifInterface 支持库,这可能会使访问 Exif 属性更容易。有关它的文章,请参阅Android 开发者博客

于 2012-10-17T11:49:17.473 回答
1

所选答案使用对此问题和类似问题的最常用回答方法。但是,它不适用于三星的前置和后置摄像头。对于那些需要适用于三星和其他主要制造商的前置和后置摄像头的另一种解决方案的人来说,nvhausid 的这个答案非常棒:

https://stackoverflow.com/a/18915443/6080472

对于那些不想点击的人来说,相关的魔法是使用 CameraInfo 而不是依赖 EXIF 或 Cursor 来处理媒体文件。

Bitmap realImage = BitmapFactory.decodeByteArray(data, 0, data.length);
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(mCurrentCameraId, info);
Bitmap bitmap = rotate(realImage, info.orientation);

链接中的完整代码。

于 2016-10-30T03:02:37.707 回答