Android相机意图(Camera Intent)在拍摄竖屏照片时保存为横屏照片

41

我查看了一下,但似乎没有一个确切的答案或解决方案来解决这个非常恼人的问题。

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

我不想强制用户在特定方向上使用相机。

是否有一种方法可以检测照片是否以纵向模式拍摄,然后解码位图并将其翻转到正确的方向?

2个回答

89

照片总是以设备内置摄像头的方向拍摄。要正确旋转图像,您需要读取存储在图片中的方向信息(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开发者博客中的一篇文章了解详情。


11
非常感谢!可惜没有办法避免(有时)需要创建第二个位图。该死的安卓及其小型虚拟机。 - Dori
1
你在哪里初始化 optsresizedBitmap - lschlessinger
2
@lschessinger,很好的发现(经过2年)。我已经更新了代码。 - Ridcully
rotatedBitmap是整个操作的结果。它包含了根据EXIF信息矫正后的图像。 - Ridcully
1
@SrujanBarai 我不这样认为:http://developer.android.com/reference/android/graphics/Matrix.html#setRotate(float) - Ridcully
显示剩余11条评论

1
所选答案使用了最常见的方法来回答这个和类似的问题。然而,在三星的前置和后置摄像头上都没有对我起作用。对于那些需要在三星和其他主要制造商的前置和后置摄像头上都能起作用的另一种解决方案,nvhausid 的答案很棒:

https://dev59.com/_mUo5IYBdhLWcg3wvBeX#18915443

对于那些不想点击的人,相关的技巧是使用CameraInfo而不是依赖于EXIF或媒体文件上的光标。
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);

在链接中查看完整的代码。


它也不起作用............. - lacas
2
mCurrentCameraId 是从哪里来的? - User

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接