Cuando puedo cargar una imagen desde la galería de medios en un mapa de bits, todo funciona bien, excepto que las fotografías que fueron tomadas con la cámara mientras sostiene el teléfono en vertical, se gira de manera que siempre tengo una horizontal de la imagen, incluso a pesar de que aparece vertical en la galería.
¿Por qué es eso y cómo puedo cargar correctamente?

InformationsquelleAutor Manuel | 2010-09-05

18 Comentarios

  1. 40

    Has mirado en los datos EXIF de las imágenes? Se puede saber la orientación de la cámara al tomar la imagen.

    • Tienes razón, eso era, por supuesto, la solución. Voy a publicar mi código como ejemplo, en un aparte de respuesta, más tarde, pero me marca este como aceptado, ya que me puso en el camino correcto.
  2. 176

    Así, como ejemplo…

    Primero necesita crear una ExifInterface:

    ExifInterface exif = new ExifInterface(filename);

    Puede a continuación, tomar la orientación de la imagen:

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

    He aquí lo que la orientación de los valores media:
    http://sylvana.net/jpegcrop/exif_orientation.html

    Así, los valores más importantes son 3, 6 y 8.
    Si la orientación es de 6, por ejemplo, se puede girar la imagen como esta:

    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. Pero usted encontrará aquellas en StackOverflow así.

    • Aquí están todos los valores de rotación por las diferentes orientaciones: 3: 180, 6: 90, 8: 270
    • No utilice los números de magia cuando usted puede utilizar constantes con nombre: ExifInterface.ORIENTATION_NORMAL, ExifInterface.ORIENTATION_ROTATE_90, ExifInterface.ORIENTATION_ROTATE_180, ExifInterface.ORIENTATION_ROTATE_270.
    • Reloj de OutOfMemoryError cuando el uso de este enfoque como sostiene dos mapas de bits en la memoria al mismo tiempo.
    • 9re publicado este util clase gist.github.com/9re/1990019
    • muchas gracias tio tu código me ha ayudado mucho!!
    • Otro ejemplo completo… stackoverflow.com/questions/14066038/…

  3. 63

    Esta es una solución completa (que se encuentra en la Hackbook ejemplo desde el Facebook SDK). Tiene la ventaja de no tener acceso al archivo en sí. Esto es muy útil si se carga una imagen desde el contenido de la resolución cosita (por ejemplo, si su aplicación es la de responder a compartir una foto de la intención).

    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, a continuación, usted puede conseguir una rotación de mapa de bits de la siguiente manera. Este código también escalas de abajo de la imagen (mal por desgracia) 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;
    }
    • lo que hace que MAX_IMAGE_DIMENDION significa?
    • Es la máxima anchura o altura de la imagen que usted consigue. I. e. Dicen que solo se necesita una imagen de 512×512, si abre un 24 megapíxeles de imagen es mucho más eficiente para abrirlo ya croma que abrir toda la cosa y, a continuación, la escala de abajo – que probablemente iba a agotar todos los de tu memoria, de todos modos.
    • En mis programas me pareció útil para definir el mapa de bits variable en la actividad/fragmento como private static y ajuste a null en las funciones. Tenía menos memoria problemas de entonces.
    • cursor es nulo.
    • Es más inteligente para reemplazar MAX_IMAGE_DIMENDION a MAX_IMAGE_WIDTH y MAX_IMAGE_HEIGHT
    • Guarda un montón de mi tiempo 🙂 Muchas gracias. Para los que obtener un cursor null, usted puede tratar de ExifInterface exif = new ExifInterface(photoUri.getPath()); y, a continuación, exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1) para obtener orientación (por ejemplo,ORIENTATION_ROTATE_90, ORIENTATION_ROTATE_180)
    • Siempre devuelve 0 en la Galaxia de Samsung S9.

  4. 59

    Solucionado en mi caso con este código de uso de la 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 le ahorra el tiempo de alguien!

    • Imagen de conseguir blurrr
    • trabajó brillantemente para mí. Gracias!
    • editar sugerencias: no hay adecuada constantes con nombre para las orientaciones de 6, 3, 8? no podríamos omitir el nuevo mapa de bits si no hay rotación es necesaria?
    • Como @d60402 dijo anteriormente en un comentario, puede utilizar constantes con nombre: ExifInterface.ORIENTATION_NORMAL, ExifInterface.ORIENTATION_ROTATE_90, ExifInterface.ORIENTATION_ROTATE_180, ExifInterface.ORIENTATION_ROTATE_270.
  5. 36

    Utilizar una Utilidad para hacer el trabajo Pesado.

    9re creado una sencilla utilidad para manejar el trabajo pesado de tratar con datos EXIF y la rotación de imágenes a su orientación correcta.

    Usted puede encontrar la utilidad de código aquí: https://gist.github.com/9re/1990019

    Simplemente descargar esta, añadir a su proyecto src directorio y el uso 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);
    • A mí me funciona ! Yo sólo cambia el tamaño de mapa de bits en formato HD antes de pasar a ExifUtil.rotateBitmap() para evitar OutOfMemoryError como que : cambia el tamaño de mapa de bits = mapa de bits.createScaledBitmap(myBitmap, 720, 1280, true); foto = ExifUtil.rotateBitmap(picturePath, cambiar de tamaño);
    • Buena adición. No he corrido en que (estoy usando más, shittier dispositivos Android) pero que es realmente bueno saber.
    • su comentario fue tan útil para mí! gracias! 😛
    • usted es un héroe de mi amigo 🙂
    • Usted acaba de hacer mi día. 🙂 Para ser justos, 9re hecho escribió la utilidad de código de modo que él es el verdadero héroe.
    • Pero sólo me preguntaba por qué necesitan tanto el imagePath y el mapa de bits original como argumentos, no es sólo la ruta de la imagen bastante 😐
    • Gran pregunta! Probablemente yo sabía por qué esto tenía sentido cuando yo era profundamente en esto, pero ahora mismo parece redundante para mí también. Ha pasado demasiado tiempo en Reaccionar Nativo, tal vez.

  6. 7

    su debido galería correcta visualización de las imágenes rotadas pero no ImageView
    mira 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;    
    } 
  7. 5

    Tengo que trabajar después de muchos intentos, gracias a un post no puedo encontrar 🙁

    Exif parece funcionar siempre, la dificultad era conseguir que la ruta de acceso. El código que he encontrado hace una diferencia entre la API mayores de 4.4 y después de 4.4. Básicamente la imagen de URI para 4.4+ contiene «com.android.los proveedores». Para este tipo de URI, el código utiliza DocumentsContract para obtener el id de imagen y, a continuación, ejecuta una consulta con el ContentResolver, mientras que para los mayores SDK, el código va directamente a la consulta de la URI con el ContentResolver.

    Aquí está el código (lo siento no puedo crédito que lo ha publicado):

    /**
    * 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);
    }
    }
    • Muchas gracias para usted. Después de horas de trabajo con los cursores y exifs, guarda este día de mayo. Como usted dijo, de hecho exif tiene la verdadera y confiable de datos en lugar de cursor devuelve. Acaba de darle la ruta correcta que funciona.
  8. 3

    Puedes leer la ruta de acceso de la tarjeta sd, y hacer el siguiente código…que va a Reemplazar el existente foto después de girar..

    No: Exif no funciona en la mayoría de los dispositivos, se da el mal de datos por lo que es bueno para codificar la rotación antes de guardar en cualquier grado que usted desea,Usted sólo tiene que cambiar el valor del ángulo en postRotate para cualquier 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();
    }
    }
    • Este es rotar pero no sabemos si la imagen necesita de rotación.
  9. 2

    He mejorado la respuesta por Teo Inke. Ya no gira 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);
    • funciona genial!
  10. 2

    La primera cosa que usted necesita es la verdadera ruta de acceso del Archivo
    Si la tienes grande, si usted está utilizando URI, a continuación, utilizar este método para
    obtener la Ruta de acceso 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;
    }

    extraer el mapa de bits, 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 así lo desea.

    Ahora que tienes el mapa de bits y el Camino real de 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 girar a la derecha de la posición 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 se gira a la posición correcta.

    saludos.

  11. 1

    Funciona esto, 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;
    }
  12. 1

    tal vez esto ayude (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;
    }
  13. 1

    El cursor debe ser cerrado después de la apertura de la misma.

    Aquí es 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;
    }
  14. 0

    La mejora en la solución anterior por Timmmm añadir algún extra de escala en el fin de asegurarse de que la imagen se ajuste 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;
    }
  15. 0

    Utilice el siguiente código 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;
    }
    • Usted puede combinar todos los si las condiciones para tener un pequeño código.
  16. 0

    Los métodos siguientes escalas Y gira el mapa de bits de acuerdo a 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());
    }
    }
  17. 0

    Me han derretido @Timmmm respuesta y @Manuel. Si usted esta solución, usted no obtendrá una carrera De Memoria Excepción.

    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, usted podría utilizar este método para cambiar el tamaño de la imagen antes de cargarlo en la memoria. De esa manera, usted no va a obtener 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 a la perfección para mí. Espero que esto ayude a alguien más

  18. -3

    He resuelto el problema con la siguiente solución. Tenga en cuenta que también estoy en la escala de la imagen, que era necesaria para evitar OutOfMemoryExceptions.

    Ten en cuenta que esta solución no funcionará correctamente con imágenes de retrato o opside-abajo las imágenes (gracias Timmmm para señalar). Timmmm la solución anterior puede ser la mejor opción si lo que se requiere y se ve mas elegante, demasiado: 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

    Saludos

    • Esto no va a funcionar correctamente. ¿Qué acerca de las imágenes de retrato? Al revés de las imágenes? Utilizando los datos exif es mucho mejor.
    • Funciona correctamente en una de mis aplicaciones, pero, por supuesto, no he probado todos los tipos de escenarios. @Timmmm ¿podría ser más específico en lo que los escenarios no funciona? También estoy bastante desconcertado acerca de usted votar mi post de abajo. Parece ser una muy dura respuesta a una honesta de intentar compartir una potencial solución.
    • No me refiero a ser duro, lo siento! Yo no quiero que nadie se copia de su solución, con la esperanza de que iba a funcionar. Como ya he dicho, no va a funcionar para retrato o al revés imágenes. Voy a añadir la solución correcta como respuesta.
    • Lo que yo veo. Voy a añadir un comentario destacando su solución anterior como el preferido uno.

Dejar respuesta

Please enter your comment!
Please enter your name here