Android: los mapas de bits cargados desde la galería se giran en ImageView

Cuando carga una imagen de la galería de medios en un mapa de bits, todo funciona bien, excepto que las imágenes que se tomaron con la cámara mientras sostenía el teléfono verticalmente, se giran de modo que siempre obtengo una imagen horizontal, aunque aparezca vertical en la imagen. galería. ¿Por qué es eso y cómo puedo cargarlo correctamente?

¿Has mirado los datos EXIF ​​de las imágenes? Puede saber la orientación de la cámara cuando se tomó la fotografía.

Por lo tanto, como un ejemplo …

Primero usted necesita crear un ExifInterface:

ExifInterface exif = new ExifInterface(filename); 

A continuación, puede tomar la orientación de la imagen:

 orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1); 

Esto es lo que significan los valores de orientación: http://sylvana.net/jpegcrop/exif_orientation.html

Por lo tanto, los valores más importantes son 3, 6 y 8. Si la orientación es 6, por ejemplo, puede girar la imagen de la siguiente manera:

 Matrix matrix = new Matrix(); matrix.postRotate(90); rotatedBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight(), matrix, true); 

Eso es sólo un ejemplo rápido, sin embargo. Estoy seguro de que hay otras maneras de realizar la rotación real. Pero también encontrarás los de StackOverflow.

Esta es una solución completa (que se encuentra en el ejemplo de Hackbook del SDK de Facebook). Tiene la ventaja de no tener acceso al archivo en sí. Esto es extremadamente útil si está cargando una imagen de la solución de contenido thingy (por ejemplo, si su aplicación está respondiendo a una intención de compartir foto).

 public static int getOrientation(Context context, Uri photoUri) { /* it's on the external media. */ Cursor cursor = context.getContentResolver().query(photoUri, new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null); if (cursor.getCount() != 1) { return -1; } cursor.moveToFirst(); return cursor.getInt(0); } 

Y entonces usted puede conseguir un mapa de bits girado como sigue. Este código también baja la imagen (mal desafortunadamente) a MAX_IMAGE_DIMENSION. De lo contrario, puede quedarse sin memoria.

 public static Bitmap getCorrectlyOrientedImage(Context context, Uri photoUri) throws IOException { InputStream is = context.getContentResolver().openInputStream(photoUri); BitmapFactory.Options dbo = new BitmapFactory.Options(); dbo.inJustDecodeBounds = true; BitmapFactory.decodeStream(is, null, dbo); is.close(); int rotatedWidth, rotatedHeight; int orientation = getOrientation(context, photoUri); if (orientation == 90 || orientation == 270) { rotatedWidth = dbo.outHeight; rotatedHeight = dbo.outWidth; } else { rotatedWidth = dbo.outWidth; rotatedHeight = dbo.outHeight; } Bitmap srcBitmap; is = context.getContentResolver().openInputStream(photoUri); if (rotatedWidth > MAX_IMAGE_DIMENSION || rotatedHeight > MAX_IMAGE_DIMENSION) { float widthRatio = ((float) rotatedWidth) / ((float) MAX_IMAGE_DIMENSION); float heightRatio = ((float) rotatedHeight) / ((float) MAX_IMAGE_DIMENSION); float maxRatio = Math.max(widthRatio, heightRatio); // Create the bitmap from file BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = (int) maxRatio; srcBitmap = BitmapFactory.decodeStream(is, null, options); } else { srcBitmap = BitmapFactory.decodeStream(is); } is.close(); /* * if the orientation is not 0 (or -1, which means we don't know), we * have to do a rotation. */ if (orientation > 0) { Matrix matrix = new Matrix(); matrix.postRotate(orientation); srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), srcBitmap.getHeight(), matrix, true); } return srcBitmap; } 

Resuelto en mi caso con este código con ayuda de este post:

  Bitmap myBitmap = getBitmap(imgFile.getAbsolutePath()); try { ExifInterface exif = new ExifInterface(imgFile.getAbsolutePath()); int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1); Log.d("EXIF", "Exif: " + orientation); Matrix matrix = new Matrix(); if (orientation == 6) { matrix.postRotate(90); } else if (orientation == 3) { matrix.postRotate(180); } else if (orientation == 8) { matrix.postRotate(270); } myBitmap = Bitmap.createBitmap(myBitmap, 0, 0, myBitmap.getWidth(), myBitmap.getHeight(), matrix, true); // rotating bitmap } catch (Exception e) { } ImageView img = (ImageView) findViewById(R.id.imgTakingPic); img.setImageBitmap(myBitmap); 

Espero que ahorre el tiempo de alguien!

Utilice una utilidad para hacer el levantamiento pesado.

9re creó una utilidad simple para manejar el levantamiento pesado de tratar con datos EXIF ​​y girar imágenes a su orientación correcta.

Puede encontrar el código de utilidad aquí: https://gist.github.com/9re/1990019

Basta con descargarlo, agregarlo al directorio src su proyecto y utilizar ExifUtil.rotateBitmap() para obtener la orientación correcta, así:

 String imagePath = photoFile.getAbsolutePath(); // photoFile is a File class. Bitmap myBitmap = BitmapFactory.decodeFile(imagePath); Bitmap orientedBitmap = ExifUtil.rotateBitmap(imagePath, myBitmap); 

Es porque la galería correcta mostrar las imágenes giradas pero no ImageView mirar aquí:

  myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath(),optionss); ExifInterface exif = new ExifInterface(selectedImagePath); int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); int rotationInDegrees = exifToDegrees(rotation); deg = rotationInDegrees; Matrix matrix = new Matrix(); if (rotation != 0f) { matrix.preRotate(rotationInDegrees); myBitmap = Bitmap.createBitmap(myBitmap, 0, 0, myBitmap.getWidth(), myBitmap.getHeight(), matrix, true); } 

Y usted necesita esto:

 private static int exifToDegrees(int exifOrientation) { if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) { return 90; } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) { return 180; } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) { return 270; } return 0; } 

Lo tengo que trabajar después de muchos intentos gracias a un mensaje que ya no puedo encontrar 🙁

Exif parece funcionar siempre, la dificultad fue para obtener el filepath. El código que encontré hace una diferencia entre API más vieja que 4.4 y después 4.4. Básicamente, la imagen URI para 4.4 + contiene "com.android.providers". Para este tipo de URI, el código utiliza DocumentsContract para obtener el id de imagen y luego ejecuta una consulta utilizando ContentResolver, mientras que para SDK más antiguo, el código pasa directamente a consultar el URI con ContentResolver.

Aquí está el código (lo siento, no puedo creer que lo publicó):

 /** * Handles pre V19 uri's * @param context * @param contentUri * @return */ public static String getPathForPreV19(Context context, Uri contentUri) { String res = null; String[] proj = { MediaStore.Images.Media.DATA }; Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null); if(cursor.moveToFirst()){; int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); res = cursor.getString(column_index); } cursor.close(); return res; } /** * Handles V19 and up uri's * @param context * @param contentUri * @return path */ @TargetApi(Build.VERSION_CODES.KITKAT) public static String getPathForV19AndUp(Context context, Uri contentUri) { String wholeID = DocumentsContract.getDocumentId(contentUri); // Split at colon, use second item in the array String id = wholeID.split(":")[1]; String[] column = { MediaStore.Images.Media.DATA }; // where id is equal to String sel = MediaStore.Images.Media._ID + "=?"; Cursor cursor = context.getContentResolver(). query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{ id }, null); String filePath = ""; int columnIndex = cursor.getColumnIndex(column[0]); if (cursor.moveToFirst()) { filePath = cursor.getString(columnIndex); } cursor.close(); return filePath; } public static String getRealPathFromURI(Context context, Uri contentUri) { String uriString = String.valueOf(contentUri); boolean goForKitKat= uriString.contains("com.android.providers"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && goForKitKat) { Log.i("KIKAT","YES"); return getPathForV19AndUp(context, contentUri); } else { return getPathForPreV19(context, contentUri); } } 

Sólo puede leer la ruta de la tarjeta sd y hacer el siguiente código … que va a reemplazar la foto existente después de rotarlo ..

No: Exif no funciona en la mayoría de los dispositivos, da los datos erróneos por lo que es bueno codificar duro la rotación antes de guardar en cualquier grado que desee, sólo tiene que cambiar el valor del ángulo en postRotate a cualquiera que desee.

  String photopath = tempphoto.getPath().toString(); Bitmap bmp = BitmapFactory.decodeFile(photopath); Matrix matrix = new Matrix(); matrix.postRotate(90); bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true); FileOutputStream fOut; try { fOut = new FileOutputStream(tempphoto); bmp.compress(Bitmap.CompressFormat.JPEG, 85, fOut); fOut.flush(); fOut.close(); } catch (FileNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } 

Lo primero que necesita es la ruta de archivo real Si lo tiene grande, si está utilizando URI, a continuación, utilice este método para obtener la ruta real:

  public static String getRealPathFromURI(Uri contentURI,Context context) { String path= contentURI.getPath(); try { Cursor cursor = context.getContentResolver().query(contentURI, null, null, null, null); cursor.moveToFirst(); String document_id = cursor.getString(0); document_id = document_id.substring(document_id.lastIndexOf(":") + 1); cursor.close(); cursor = context.getContentResolver().query( android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null); cursor.moveToFirst(); path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)); cursor.close(); } catch(Exception e) { return path; } return path; } 

Extraiga su Bitmap por ejemplo:

  try { Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage); } catch (IOException e) { Log.e("IOException",e.toString()); } 

Puede utilizar decodeFile () en su lugar si lo desea.

Ahora que tiene el mapa de bits y el camino real obtener la orientación de la imagen:

  private static int getExifOrientation(String src) throws IOException { int orientation = 1; ExifInterface exif = new ExifInterface(src); String orientationString=exif.getAttribute(ExifInterface.TAG_ORIENTATION); try { orientation = Integer.parseInt(orientationString); } catch(NumberFormatException e){} return orientation; } 

Y finalmente gírelo a la posición correcta como así:

 public static Bitmap rotateBitmap(String src, Bitmap bitmap) { try { int orientation = getExifOrientation(src); if (orientation == 1) { return bitmap; } Matrix matrix = new Matrix(); switch (orientation) { case 2: matrix.setScale(-1, 1); break; case 3: matrix.setRotate(180); break; case 4: matrix.setRotate(180); matrix.postScale(-1, 1); break; case 5: matrix.setRotate(90); matrix.postScale(-1, 1); break; case 6: matrix.setRotate(90); break; case 7: matrix.setRotate(-90); matrix.postScale(-1, 1); break; case 8: matrix.setRotate(-90); break; default: return bitmap; } try { Bitmap oriented = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); bitmap.recycle(); return oriented; } catch (OutOfMemoryError e) { e.printStackTrace(); return bitmap; } } catch (IOException e) { e.printStackTrace(); } return bitmap; } 

Eso es todo, ahora tiene el mapa de bits rotado a la posición correcta.

aclamaciones.

Esto funciona, pero probablemente no es la mejor manera de hacerlo, pero podría ayudar a alguien.

 String imagepath = someUri.getAbsolutePath(); imageview = (ImageView)findViewById(R.id.imageview); imageview.setImageBitmap(setImage(imagepath, 120, 120)); public Bitmap setImage(String path, final int targetWidth, final int targetHeight) { Bitmap bitmap = null; // Get exif orientation try { ExifInterface exif = new ExifInterface(path); int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1); if (orientation == 6) { orientation_val = 90; } else if (orientation == 3) { orientation_val = 180; } else if (orientation == 8) { orientation_val = 270; } } catch (Exception e) { } try { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); // Adjust extents int sourceWidth, sourceHeight; if (orientation_val == 90 || orientation_val == 270) { sourceWidth = options.outHeight; sourceHeight = options.outWidth; } else { sourceWidth = options.outWidth; sourceHeight = options.outHeight; } // Calculate the maximum required scaling ratio if required and load the bitmap if (sourceWidth > targetWidth || sourceHeight > targetHeight) { float widthRatio = (float)sourceWidth / (float)targetWidth; float heightRatio = (float)sourceHeight / (float)targetHeight; float maxRatio = Math.max(widthRatio, heightRatio); options.inJustDecodeBounds = false; options.inSampleSize = (int)maxRatio; bitmap = BitmapFactory.decodeFile(path, options); } else { bitmap = BitmapFactory.decodeFile(path); } // Rotate the bitmap if required if (orientation_val > 0) { Matrix matrix = new Matrix(); matrix.postRotate(orientation_val); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } // Re-scale the bitmap if necessary sourceWidth = bitmap.getWidth(); sourceHeight = bitmap.getHeight(); if (sourceWidth != targetWidth || sourceHeight != targetHeight) { float widthRatio = (float)sourceWidth / (float)targetWidth; float heightRatio = (float)sourceHeight / (float)targetHeight; float maxRatio = Math.max(widthRatio, heightRatio); sourceWidth = (int)((float)sourceWidth / maxRatio); sourceHeight = (int)((float)sourceHeight / maxRatio); bitmap = Bitmap.createScaledBitmap(bitmap, sourceWidth, sourceHeight, true); } } catch (Exception e) { } return bitmap; } 

Utilice el código siguiente para girar una imagen correctamente:

 private Bitmap rotateImage(Bitmap bitmap, String filePath) { Bitmap resultBitmap = bitmap; try { ExifInterface exifInterface = new ExifInterface(filePath); int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1); Matrix matrix = new Matrix(); if (orientation == ExifInterface.ORIENTATION_ROTATE_90) { matrix.postRotate(ExifInterface.ORIENTATION_ROTATE_90); } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) { matrix.postRotate(ExifInterface.ORIENTATION_ROTATE_180); } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) { matrix.postRotate(ExifInterface.ORIENTATION_ROTATE_270); } // Rotate the bitmap resultBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } catch (Exception exception) { Logger.d("Could not rotate the image"); } return resultBitmap; } 

Tal vez esto ayudará (girar 90 grados) (esto funcionó para mí)

 private Bitmap rotateBitmap(Bitmap image){ int width=image.getHeight(); int height=image.getWidth(); Bitmap srcBitmap=Bitmap.createBitmap(width, height, image.getConfig()); for (int y=width-1;y>=0;y--) for(int x=0;x<height;x++) srcBitmap.setPixel(width-y-1, x,image.getPixel(x, y)); return srcBitmap; } 

He mejorado la respuesta de Teo Inke. Ya no rota la imagen a menos que sea realmente necesario. También es más fácil de leer, y debe correr más rápido.

 // Load Image Bitmap bitmap = BitmapFactory.decodeFile(filePath); // Rotate Image if Needed try { // Determine Orientation ExifInterface exif = new ExifInterface(filePath); int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1); // Determine Rotation int rotation = 0; if (orientation == 6) rotation = 90; else if (orientation == 3) rotation = 180; else if (orientation == 8) rotation = 270; // Rotate Image if Necessary if (rotation != 0) { // Create Matrix Matrix matrix = new Matrix(); matrix.postRotate(rotation); // Rotate Bitmap Bitmap rotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); // Pretend none of this ever happened! bitmap.recycle(); bitmap = rotated; rotated = null; } } catch (Exception e) { // TODO: Log Error Messages Here } // TODO: Use Result Here xxx.setBitmap(bitmap); 

El cursor debe estar cerrado después de abrirlo.

Aquí hay un ejemplo.

  public static int getOrientation(Context context, Uri selectedImage) { int orientation = -1; Cursor cursor = context.getContentResolver().query(selectedImage, new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null); if (cursor.getCount() != 1) return orientation; cursor.moveToFirst(); orientation = cursor.getInt(0); cursor.close(); // ADD THIS LINE return orientation; } 

Mejora de la solución anterior por Timmmm para añadir un poco de escala adicional al final para asegurarse de que la imagen encaja dentro de los límites:

 public static Bitmap loadBitmap(String path, int orientation, final int targetWidth, final int targetHeight) { Bitmap bitmap = null; try { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); // Adjust extents int sourceWidth, sourceHeight; if (orientation == 90 || orientation == 270) { sourceWidth = options.outHeight; sourceHeight = options.outWidth; } else { sourceWidth = options.outWidth; sourceHeight = options.outHeight; } // Calculate the maximum required scaling ratio if required and load the bitmap if (sourceWidth > targetWidth || sourceHeight > targetHeight) { float widthRatio = (float)sourceWidth / (float)targetWidth; float heightRatio = (float)sourceHeight / (float)targetHeight; float maxRatio = Math.max(widthRatio, heightRatio); options.inJustDecodeBounds = false; options.inSampleSize = (int)maxRatio; bitmap = BitmapFactory.decodeFile(path, options); } else { bitmap = BitmapFactory.decodeFile(path); } // Rotate the bitmap if required if (orientation > 0) { Matrix matrix = new Matrix(); matrix.postRotate(orientation); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } // Re-scale the bitmap if necessary sourceWidth = bitmap.getWidth(); sourceHeight = bitmap.getHeight(); if (sourceWidth != targetWidth || sourceHeight != targetHeight) { float widthRatio = (float)sourceWidth / (float)targetWidth; float heightRatio = (float)sourceHeight / (float)targetHeight; float maxRatio = Math.max(widthRatio, heightRatio); sourceWidth = (int)((float)sourceWidth / maxRatio); sourceHeight = (int)((float)sourceHeight / maxRatio); bitmap = Bitmap.createScaledBitmap(bitmap, sourceWidth, sourceHeight, true); } } catch (Exception e) { } return bitmap; } 

Los métodos descritos a continuación escalan y giran el mapa de bits de acuerdo con la orientación:

 public Bitmap scaleAndRotateImage(String path, int orientation, final int targetWidth, final int targetHeight) { Bitmap bitmap = null; try { // Check the dimensions of the Image final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); // Adjust the Width and Height int sourceWidth, sourceHeight; if (orientation == 90 || orientation == 270) { sourceWidth = options.outHeight; sourceHeight = options.outWidth; } else { sourceWidth = options.outWidth; sourceHeight = options.outHeight; } // Calculate the maximum required scaling ratio if required and load the bitmap if (sourceWidth > targetWidth || sourceHeight > targetHeight) { float widthRatio = (float)sourceWidth / (float)targetWidth; float heightRatio = (float)sourceHeight / (float)targetHeight; float maxRatio = Math.max(widthRatio, heightRatio); options.inJustDecodeBounds = false; options.inSampleSize = (int)maxRatio; bitmap = BitmapFactory.decodeFile(path, options); } else { bitmap = BitmapFactory.decodeFile(path); } // We need to rotate the bitmap (if required) int orientationInDegrees = exifToDegrees(orientation); if (orientation > 0) { Matrix matrix = new Matrix(); if (orientation != 0f) { matrix.preRotate(orientationInDegrees); }; bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } // Re-scale the bitmap if necessary sourceWidth = bitmap.getWidth(); sourceHeight = bitmap.getHeight(); if (sourceWidth != targetWidth || sourceHeight != targetHeight) { float widthRatio = (float)sourceWidth / (float)targetWidth; float heightRatio = (float)sourceHeight / (float)targetHeight; float maxRatio = Math.max(widthRatio, heightRatio); sourceWidth = (int)((float)sourceWidth / maxRatio); sourceHeight = (int)((float)sourceHeight / maxRatio); bitmap = Bitmap.createScaledBitmap(bitmap, sourceWidth, sourceHeight, true); } } catch (Exception e) { Logger.d("Could not rotate the image"); Logger.d(e.getMessage()); } return bitmap; } 

Ejemplo:

 public void getPictureFromDevice(Uri Uri,ImageView imageView) { try { ExifInterface exifInterface = new ExifInterface(Uri.getPath()); int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); Bitmap bitmap = scaleAndRotateImage(Uri.getPath(), orientation, imageView.getWidth(), imageView.getHeight()); imageView.setImageBitmap(bitmap); } catch (OutOfMemoryError outOfMemoryError) { Logger.d(outOfMemoryError.getLocalizedMessage()); Logger.d("Failed to load image from filePath (out of memory)"); Logger.d(Uri.toString()); } catch (Exception e) { Logger.d("Failed to load image from filePath"); Logger.d(Uri.toString()); } } 

He derretido @Timmmm respuesta y @Manuel. Si haces esta solución, no obtendrás una Excepción de Excepción de Memoria.

Este método recupera la orientación de la imagen:

 private static final int ROTATION_DEGREES = 90; // This means 512 px private static final Integer MAX_IMAGE_DIMENSION = 512; public static int getOrientation(Uri photoUri) throws IOException { ExifInterface exif = new ExifInterface(photoUri.getPath()); int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: orientation = ROTATION_DEGREES; break; case ExifInterface.ORIENTATION_ROTATE_180: orientation = ROTATION_DEGREES * 2; break; case ExifInterface.ORIENTATION_ROTATE_270: orientation = ROTATION_DEGREES * 3; break; default: // Default case, image is not rotated orientation = 0; } return orientation; } 

Por lo tanto, debería utilizar este método para cambiar el tamaño de la imagen antes de cargarla en la memoria. De esa manera, no obtendrá una excepción de memoria.

 public static Bitmap getCorrectlyOrientedImage(Context context, Uri photoUri) throws IOException { InputStream is = context.getContentResolver().openInputStream(photoUri); BitmapFactory.Options dbo = new BitmapFactory.Options(); dbo.inJustDecodeBounds = true; BitmapFactory.decodeStream(is, null, dbo); is.close(); int rotatedWidth, rotatedHeight; int orientation = getOrientation(photoUri); if (orientation == 90 || orientation == 270) { rotatedWidth = dbo.outHeight; rotatedHeight = dbo.outWidth; } else { rotatedWidth = dbo.outWidth; rotatedHeight = dbo.outHeight; } Bitmap srcBitmap; is = context.getContentResolver().openInputStream(photoUri); if (rotatedWidth > MAX_IMAGE_DIMENSION || rotatedHeight > MAX_IMAGE_DIMENSION) { float widthRatio = ((float) rotatedWidth) / ((float) MAX_IMAGE_DIMENSION); float heightRatio = ((float) rotatedHeight) / ((float) MAX_IMAGE_DIMENSION); float maxRatio = Math.max(widthRatio, heightRatio); // Create the bitmap from file BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = (int) maxRatio; srcBitmap = BitmapFactory.decodeStream(is, null, options); } else { srcBitmap = BitmapFactory.decodeStream(is); } is.close(); // if the orientation is not 0, we have to do a rotation. if (orientation > 0) { Matrix matrix = new Matrix(); matrix.postRotate(orientation); srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), srcBitmap.getHeight(), matrix, true); } return srcBitmap; } 

Esto funciona perfectamente para mí. Espero que esto ayude a alguien más

Solucioné el problema con la solución siguiente. Tenga en cuenta que también estoy escalando la imagen, que era necesario para evitar OutOfMemoryExceptions.

Tenga cuidado de que esta solución no funcionará correctamente con imágenes de retrato o imágenes opuestas (gracias Timmmm por anotar). La solución de Timmmm anterior podría ser la mejor opción si se requiere y parece más elegante, también: https://stackoverflow.com/a/8914291/449918

 File path = // ... location of your bitmap file int w = 512; int h = 384; // size that does not lead to OutOfMemoryException on Nexus One Bitmap b = BitmapFactory.decodeFile(path); // Hack to determine whether the image is rotated boolean rotated = b.getWidth() > b.getHeight(); Bitmap resultBmp = null; // If not rotated, just scale it if (!rotated) { resultBmp = Bitmap.createScaledBitmap(b, w, h, true); b.recycle(); b = null; // If rotated, scale it by switching width and height and then rotated it } else { Bitmap scaledBmp = Bitmap.createScaledBitmap(b, h, w, true); b.recycle(); b = null; Matrix mat = new Matrix(); mat.postRotate(90); resultBmp = Bitmap.createBitmap(scaledBmp, 0, 0, h, w, mat, true); // Release image resources scaledBmp.recycle(); scaledBmp = null; } // resultBmp now contains the scaled and rotated image 

Aclamaciones

  • Recomponer Disposición de actividad para reproducir vídeo en pantalla completa cuando se gira la pantalla
  • Sprite Rotación en Android con Canvas.DrawBitmap. Estoy cerca, ¿qué estoy haciendo mal?
  • Lienzo dirección drawtext
  • Android: Manejo eficiente de la rotación de la pantalla
  • Rotar una imagen en Android sin OutOfMemoryError o downscaling
  • Gire la vista de imagen alrededor de su centro sin cortar sus bordes
  • Rotar MapView en Android
  • Android visualiza la transformación de rotación 3D en pantallas de gran resolución
  • Android: gira la imagen en la vista de la imagen por un ángulo
  • Cómo rotar Bitmap sin crear uno nuevo?
  • Obtener rotación y mostrar en grados
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.