Android Camera Intent Saving Image Landscape cuando se toma el retrato

He echado un vistazo pero no parece haber una respuesta / solución sólida al problema, muy irritante.

Tomo una foto en orientación vertical y cuando presiono guardar / descartar, los botones también están en la orientación correcta. El problema es cuando recupero la imagen más tarde en orientación horizontal (la imagen se ha girado 90 grados en sentido antihorario)

No quiero obligar al usuario a usar la cámara con una orientación determinada.

¿Hay alguna forma de detectar si la foto se tomó en modo vertical y luego decodificar el bitmap y voltearlo hacia arriba?

La imagen siempre se toma en la orientación de la cámara en el dispositivo. Para que su imagen gire correctamente, tendrá que leer la información de orientación que está almacenada en la imagen (metadatos EXIF). Allí se almacena cómo se orientó el dispositivo, cuándo se tomó la imagen.

Aquí hay un código que lee los datos EXIF ​​y gira la imagen en consecuencia: file es el nombre del archivo de imagen.

 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); 

ACTUALIZACIÓN 2017-01-16

Con el lanzamiento de la Biblioteca de soporte 25.1.0, se introdujo una Biblioteca de soporte ExifInterface, que quizás debería facilitar el acceso a los atributos de Exif. Consulte el Blog del desarrollador de Android para obtener un artículo al respecto.

La respuesta seleccionada utiliza el método más común que se responde a esta y preguntas similares. Sin embargo, no funcionó para mí con cámaras frontal y posterior en Samsung. Para aquellos que necesitan otra solución que funcione tanto en cámaras frontales como traseras para Samsung y otros fabricantes importantes, esta respuesta de nvhausid es asombrosa:

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

Para aquellos que no quieren hacer clic, la magia relevante es usar CameraInfo en lugar de confiar en EXIF ​​o un Cursor sobre los archivos multimedia.

 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); 

Código completo en el enlace.