web-dev-qa-db-fra.com

Comment obtenir l'orientation correcte de l'image sélectionnée dans la galerie d'images par défaut

J'ai parcouru certains des liens pour obtenir la bonne orientation d'image de l'image sélectionnée dans la galerie d'images par défaut à utiliser en standard dans tous les appareils. La balise exif renvoie toujours 0.

valeur de balise d’orientation EXIF ​​toujours égale à 0 pour une image prise avec l’application portrait de l’application Android

la balise d'orientation Exif renvoie

données Exif TAG_ORIENTATION toujours

http://mobisocial.stanford.edu/news/2011/08/rotating-images-in-Android/

Comment obtenir une solution exacte qui fonctionnera sur tous les appareils?

35
ramsraj111

Si l'image (photo) a été prise par un programme que vous avez créé, vous devez définir Parameters.setRotation avec la valeur de rotation correcte.

Cela, en fonction du lecteur de caméra, fait pivoter l'image avant de sauvegarder ou enregistre la valeur de rotation sur exif TAG_ORIENTATION.

Par conséquent, si TAG_ORIENTATION est nul ou égal à zéro, les images sont orientées correctement. Sinon, vous devez faire pivoter l'image en fonction de la valeur de TAG_ORIENTATION.

CODE

Obtenez l'orientation de EXIF:

ExifInterface exif = null;
try {
    exif = new ExifInterface(path);
} catch (IOException e) {
    e.printStackTrace();
}  
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 
                                       ExifInterface.ORIENTATION_UNDEFINED);

Faire pivoter l'image bitmap:

Bitmap bmRotated = rotateBitmap(bitmap, orientation);  

Méthode pour faire pivoter un bitmap:

public static Bitmap rotateBitmap(Bitmap bitmap, int orientation) {

    Matrix matrix = new Matrix();
    switch (orientation) {
        case ExifInterface.ORIENTATION_NORMAL:
            return bitmap;
        case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
            matrix.setScale(-1, 1);
            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            matrix.setRotate(180);
            break;
        case ExifInterface.ORIENTATION_FLIP_VERTICAL:
            matrix.setRotate(180);
            matrix.postScale(-1, 1);
            break;
        case ExifInterface.ORIENTATION_TRANSPOSE:
            matrix.setRotate(90);
            matrix.postScale(-1, 1);
            break;
       case ExifInterface.ORIENTATION_ROTATE_90:
           matrix.setRotate(90);
           break;
       case ExifInterface.ORIENTATION_TRANSVERSE:
           matrix.setRotate(-90);
           matrix.postScale(-1, 1);
           break;
       case ExifInterface.ORIENTATION_ROTATE_270:
           matrix.setRotate(-90);
           break;
       default:
           return bitmap;
    }
    try {
        Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        bitmap.recycle();
        return bmRotated;
    }
    catch (OutOfMemoryError e) {
        e.printStackTrace();
        return null;
    }
}
103
ramaral

J'ai suivi la dernière réponse et j'ai essayé de créer un système pour gérer les images, faire pivoter, redimensionner, mettre en cache et charger dans ImageViews et je peux dire que c'est un enfer. Même lorsque tout cela est fait, des plantages sont parfois causés par OutOfMemory dans certains appareils. La réponse est correcte, mais il est difficile de gérer les bitmaps dans Android.

Mon but est de ne pas réinventer la roue, elle a un design parfait. Google lui-même vous encourage à utiliser Glide . Il fonctionne sur une seule ligne, très facile à utiliser, de taille et de nombre de fonctions légers, , il gère EXIF ​​par défaut et utilise la mémoire comme un charme. C'est simplement de la magie noire codée;)

Je ne sais pas si Picasso gère également EXIF, mais il existe une introduction rapide aux deux:

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

Mon conseil: ne perdez pas votre temps et utilisez-les. Vous pouvez résoudre votre problème en une seule ligne:

Glide.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
3
Santi Iglesias

Pour moi, ExifInterface a très bien fonctionné comme ceci:

ExifInterface exifInterface = new ExifInterface(imagePath);
degree = Integer.parseInt(exifInterface.getAttribute(ExifInterface.TAG_ORIENTATION));

ou vous pouvez essayer d'obtenir les détails de l'image en utilisant MediaStore comme ceci:

String[] orientationColumn = {MediaStore.Images.Media.ORIENTATION};
Cursor cur = managedQuery(imageUri, orientationColumn, null, null, null);
int orientation = -1;
if (cur != null && cur.moveToFirst()) {
    orientation = cur.getInt(cur.getColumnIndex(orientationColumn[0]));
} 

Solution similaire: ExifInterface renvoie toujours 1

J'espère que ça aide.. :)

3
Ankit Popli

Pour ceux qui viennent dans ce post, assurez-vous d'utiliser l'exifinterface de la Android Bibliothèque de support introduite en décembre 2016:

compile "com.Android.support:exifinterface:25.1.0" // or newer

Vous trouverez des informations détaillées sur cette bibliothèque dans la Android Blog des développeurs: . Présentation de la bibliothèque de support ExifInterface

Ils ont également inclus un exemple de code permettant de gérer les informations de rotation stockées dans l'interface exif:

int rotation = 0;
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

switch (orientation) {
   case ExifInterface.ORIENTATION_ROTATE_90:
     rotation = 90;
     break;
  case ExifInterface.ORIENTATION_ROTATE_180:
     rotation = 180;
     break;
  case ExifInterface.ORIENTATION_ROTATE_270:
     rotation = 270;
     break;
}
1
Mehlyfication