2011-09-02 23 views
46

tengo este código:Android get Orientación de una cámara Bitmap? Y gire hacia atrás -90 grados

//choosed a picture 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 

    if (resultCode == RESULT_OK) { 
     if (requestCode == ImageHelper.SELECT_PICTURE) { 

      String picture   = ""; 

      Uri selectedImageUri  = data.getData(); 
      //OI FILE Manager 
      String filemanagerstring = selectedImageUri.getPath(); 
      //MEDIA GALLERY 
      String selectedImagePath = ImageHelper.getPath(mycontext, selectedImageUri); 

      picture=(selectedImagePath!=null)?selectedImagePath:filemanagerstring; 

...

esto es sólo un selector de imagen, de la galería. esto es agradable, pero cuando abrí esta imagen en una vista de imagen, las imágenes cuando se tomaron "MODO RETRATO" con la cámara se ven bien, pero las imágenes tomaron "MODO LLANTA" con la cámara, abriéndose a -90 grados.

¿Cómo puedo volver a girar esas imágenes?

Bitmap output  = Bitmap.createBitmap(newwidth, newheight, Config.ARGB_8888); 
    Canvas canvas  = new Canvas(output); 

He intentado esto:

Log.e("w h", bitmap.getWidth()+" "+bitmap.getHeight()); 
if (bitmap.getWidth()<bitmap.getHeight()) canvas.rotate(-90); 

pero esto no funciona, todos tamaño de la imagen es: * 2.560 1.920 píxeles (vertical, y el modo PAISAJE todos)

¿Qué puedo hacer para girar hacia atrás las imágenes LANDSCAPE?

gracias Leslie

Respuesta

178

Si se toma una foto con una cámara digital o un teléfono inteligente, la rotación se almacena a menudo en los datos de la fotografía Exif, como parte del archivo de imagen. Puede leer los metadatos Exif de una imagen usando Android ExifInterface.

En primer lugar, crear la ExifInterface:

ExifInterface exif = new ExifInterface(uri.getPath()); 

A continuación, encontrará la rotación actual:

int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); 

Convertir rotación Exif a grados:

int rotationInDegrees = exifToDegrees(rotation); 

donde

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

A continuación, utilice la rotación real de la imagen como punto de referencia para girar la imagen con Matrix.

Matrix matrix = new Matrix(); 
if (rotation != 0f) {matrix.preRotate(rotationInDegrees);} 

de crear la nueva imagen rotada con el método Bitmap.createBitmap que tomar una Matrix como parámetro:

Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter) 

donde Matrix m sostiene la nueva rotación:

Bitmap adjustedBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, width, height, matrix, true); 

Consulte estos tutoriales para ejemplos útiles del código fuente:

+0

Gran respuesta, pero ¿cómo se usa la "rotación" int en Matrix? – Cole

+0

@ Cole - He editado mi respuesta para incluir una explicación de cómo usar la variable de rotación con la matriz. –

+2

¡Gracias por una respuesta tan completa! – Cole

0

Última respuesta fue técnicamente perfecta, pero traté de crear un sistema para administrar imágenes, rotar, cambiar el tamaño, almacenar en caché y cargar en ImageViews y puedo decir que es un infierno.Incluso cuando todo estaba hecho, los bloqueos a veces causan OutOfMemory en algunos dispositivos.

Mi punto es no reinventar la rueda, tiene un diseño perfecto. Google mismo lo alienta a usar Glide. Funciona en una línea, súper fácil de usar, liviano en tamaño y número de funciones, administra EXIF ​​de manera predeterminada, y usa memoria como un amuleto ... Simplemente está codificado con magia negra;)

Estoy no estoy seguro si Picasso también gestiona EXIF, pero hay una rápida introducción a ambos:

https://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en

Mi consejo: no pierda su tiempo y utilizarlos. Puede resolver su problema en una sola línea:

Glide.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView); 
+0

Sí, pero el problema es que si ha descodificado/reducido la muestra un poco por ejemplo o comprimido usando el formato jpeg. EXIF ​​no se conserva, por lo que debe restablecer los atributos al nuevo archivo. – ngatirauks

Cuestiones relacionadas