101 votes

Problème d'orientation de l'appareil photo dans Android

Je construis une application qui utilise la caméra pour prendre des photos. Voici mon code source pour faire cela :

        File file = new File(Environment.getExternalStorageDirectory(),
            imageFileName);
    imageFilePath = file.getPath();
    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
    //Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
    startActivityForResult(intent, ACTIVITY_NATIVE_CAMERA_AQUIRE);

Sur onActivityResult() j'utilise la méthode BitmapFactory.decodeStream() pour ramasser l'image.

Lorsque je lance mon application sur le Nexus one, elle fonctionne bien. Mais lorsque je l'exécute sur le Samsung Galaxy S ou le HTC Inspire 4G, la direction de l'image n'est pas correcte.

  • Lors de la capture en mode portrait, l'image réelle (enregistrée sur la carte SD) tourne toujours de 90 degrés.

image preview after shotreal image on SD card

Aperçu de l'image après la prise de vue --------- Image réelle sur la carte SD

  • Capture avec le mode paysage, tout est bon.

Image preview after shotReal image on SD card

Aperçu de l'image après la prise de vue --------- Image réelle sur la carte SD

1 votes

SetRotation(90) a fonctionné pour moi dans Samsung Galaxy Nexus, alors qu'il n'a pas fait tourner l'image dans Xperia S.

0 votes

Quelqu'un peut-il m'aider ? J'ai le même problème. stackoverflow.com/questions/28379130/

0 votes

53voto

ramz Points 676

Il y a pas mal de sujets et de questions similaires par ici. Puisque vous n'écrivez pas votre propre caméra, je pense que ça se résume à ça :

Certains appareils font pivoter l'image avant de l'enregistrer, tandis que d'autres ajoutent simplement la balise d'orientation dans les données exif de la photo.

Je vous recommande de vérifier les données exif de la photo et de rechercher en particulier

ExifInterface exif = new ExifInterface(SourceFileName);     //Since API Level 5
String exifOrientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);

Puisque la photo s'affiche correctement dans votre application, je ne suis pas sûr de l'origine du problème, mais cela devrait vous mettre sur la bonne voie !

34 votes

Cela ne semble pas fonctionner sur certains appareils, il retourne 0 pour toutes les orientations Je sais que cela arrive sur le Galaxy S Infuse et le Sony Xperia Arc, et S II Ce qui est intéressant ici, c'est que lorsque ces mêmes images sont sélectionnées dans la galerie, le fournisseur de contenu a la valeur d'orientation appropriée Une idée ?

0 votes

Ici, le nom de la source est le chemin d'accès complet du fichier.

0 votes

@TolgaE Vous avez raison. Il renvoie 0 pour certains appareils, dont DroidX. Je travaille actuellement sur une solution. Je ne sais pas si elle va fonctionner.

28voto

Michael Herbig Points 1154

Je viens de rencontrer le même problème, et j'ai utilisé ceci pour corriger l'orientation :

public void fixOrientation() {
    if (mBitmap.getWidth() > mBitmap.getHeight()) {
        Matrix matrix = new Matrix();
        matrix.postRotate(90);
        mBitmap = Bitmap.createBitmap(mBitmap , 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true);
    }
}

Si la largeur du bitmap est supérieure à la hauteur, l'image renvoyée est en paysage, je la fais donc pivoter de 90 degrés.

J'espère que cela aidera toute autre personne confrontée à ce problème.

19 votes

Et si l'image était en fait prise en paysage ? Votre code le fera toujours pivoter. Ce n'est pas une réponse à la question.

1 votes

Mon application force le portrait, donc ce n'est pas un problème. Je ne l'ai inclus ici que comme solution alternative au problème.

5 votes

Mais si l'application force le portrait, vous pouvez toujours prendre une photo en mode paysage (largeur > hauteur) et elle sera tournée... C'est du moins ce que j'obtiens en paramétrant screenOrientation="portrait" pour tout... l'appareil peut toujours prendre des photos en mode paysage.

22voto

Tran Khanh Tung Points 71

Il y a deux choses nécessaires :

  1. L'aperçu de la caméra doit être identique à votre rotation. Définissez ceci par camera.setDisplayOrientation(result);

  2. Enregistrez l'image capturée comme aperçu de votre appareil photo. Pour ce faire, utilisez Camera.Parameters .

    int mRotation = getCameraDisplayOrientation();
    
    Camera.Parameters parameters = camera.getParameters();
    
    parameters.setRotation(mRotation); //set rotation to save the picture
    
    camera.setDisplayOrientation(result); //set the rotation for preview camera
    
    camera.setParameters(parameters);

J'espère que cela vous aidera.

0 votes

C'est ici ! Camera.parameters est vraiment pratique pour sauvegarder des instantanés sans faire un rendu intermédiaire en bitmap.

0 votes

Veuillez marquer cette réponse comme étant la plus facile ! Cela fait l'affaire ! Très heureux de cette solution facile

0 votes

Si cet extrait est pris tel quel, nous pourrions simplement dire que parameters.setRotation(result) Non ?

10voto

vineet pal Points 41
            int rotate = 0;
            try {
                File imageFile = new File(sourcepath);
                ExifInterface exif = new ExifInterface(
                        imageFile.getAbsolutePath());
                int orientation = exif.getAttributeInt(
                        ExifInterface.TAG_ORIENTATION,
                        ExifInterface.ORIENTATION_NORMAL);

                switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_270:
                    rotate = 270;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    rotate = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_90:
                    rotate = 90;
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            Matrix matrix = new Matrix();
    matrix.postRotate(rotate);
    bitmap = Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);

0 votes

Il serait utile d'avoir quelques explications sur ce que fait votre code, et comment il fait les choses différemment des autres réponses (la question est après tout déjà assez ancienne, et les autres réponses sont donc probablement assez matures).

7voto

Emilio Points 990

Une autre option consiste à faire pivoter le bitmap dans l'écran des résultats comme ceci :

ImageView img=(ImageView)findViewById(R.id.ImageView01);
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.refresh);
// Getting width & height of the given image.
int w = bmp.getWidth();
int h = bmp.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
mtx.postRotate(90);
// Rotating Bitmap
Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, w, h, mtx, true);
BitmapDrawable bmd = new BitmapDrawable(rotatedBMP);

img.setImageDrawable(bmd);

30 votes

Cette approche ne fonctionnera pas, car elle fait également pivoter les images provenant d'appareils qui gèrent correctement l'orientation.

0 votes

Réponse complète et correcte présente ici stackoverflow.com/questions/6069122/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X