web-dev-qa-db-fra.com

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

Je construis une application qui utilise l'appareil photo pour prendre des photos. Voici mon code source pour le faire:

        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 la méthode onActivityResult(), j'utilise BitmapFactory.decodeStream() pour prendre l'image.

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

  • Capture en mode portrait, l'image réelle (enregistrée sur une carte SD) pivote 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

  • Capturez en mode paysage, tout va bien.

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

98
Nguyen Minh Binh

Il y a pas mal de sujets et de problèmes similaires ici. Puisque vous n'écrivez pas votre propre caméra, je pense que cela se résume à ceci:

certains périphériques 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);

Étant donné que la photo s'affiche correctement dans votre application, je ne suis pas sûr du problème, mais cela devrait vous mettre sur la bonne voie!

50
ramz

Je viens de rencontrer le même problème et je l’ai utilisé 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 mode paysage, je la fais donc pivoter de 90 degrés.

J'espère que cela aidera quelqu'un d'autre avec ce problème.

28
user901309

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 en tant qu'aperçu de votre caméra. Faites ceci via 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 ça t'as aidé.

21
Tran Khanh Tung
            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);
10
vineet pal

Une autre option consiste à faire pivoter le bitmap dans l'écran de résultat comme suit:

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);
7
PakitoV

J'ai aussi ce type de problème pour certains appareils:

private void rotateImage(final String path) {

    Bitmap scaledBitmap = Bitmap.createScaledBitmap(Conasants.bm1, 1000,
            700, true);
    Bitmap rotatedBitmap = null;
    try {
        ExifInterface ei = new ExifInterface(path);
        int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);
        Matrix matrix = new Matrix();
        switch (orientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
            matrix.postRotate(90);
            rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
                    scaledBitmap.getWidth(), scaledBitmap.getHeight(),
                    matrix, true);
            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            matrix.postRotate(180);
            rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
                    scaledBitmap.getWidth(), scaledBitmap.getHeight(),
                    matrix, true);
            break;
        case ExifInterface.ORIENTATION_ROTATE_270:
            matrix.postRotate(270);
            rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
                    scaledBitmap.getWidth(), scaledBitmap.getHeight(),
                    matrix, true);
            break;
        default:
            rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
                    scaledBitmap.getWidth(), scaledBitmap.getHeight(),
                    matrix, true);
            break;
        }
    } catch (Throwable e) {
        e.printStackTrace();
    }
    cropImage.setImageBitmap(rotatedBitmap);
    rotatedBitmap = null;
    Conasants.bm1 = null;
}
3
patel135

Plus besoin de vérifier les données exif de la photo. Allez-y doucement avec Glide .

Google nous a présenté une bibliothèque Image Loader pour Android développée par bumptech nommée Glide comme une bibliothèque recommandée par Google. Elle a été utilisé dans de nombreux projets Google open source jusqu'à présent, y compris l'application officielle de Google I/O 2014.

Ex: Glide.with (contexte) .load (uri) .into (imageview);

Pour plus: https://github.com/bumptech/glide

1
S.Prapagorn

Essayez de cette façon: Uri statique image_uri; static Bitmap taken_image = null;

            image_uri=fileUri; // file where image has been saved

      taken_image=BitmapFactory.decodeFile(image_uri.getPath());
      try
        {
            ExifInterface exif = new ExifInterface(image_uri.getPath()); 

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


            switch(orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
                    RotateBitmap(taken_image, 90);
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
                    RotateBitmap(taken_image, 180);

                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
                    RotateBitmap(taken_image, 270);

                    break;
                case ExifInterface.ORIENTATION_NORMAL:
                    taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
                    RotateBitmap(taken_image, 0);

                    break;
            }

        }
        catch (OutOfMemoryError e)
        {
            Toast.makeText(getActivity(),e+"\"memory exception occured\"",Toast.LENGTH_LONG).show();


        }



public Bitmap RotateBitmap(Bitmap source, float angle) {
      Matrix matrix = new Matrix();
      matrix.postRotate(angle);

      round_Image = source;
      round_Image = Bitmap.createBitmap(source, 0, 0, source.getWidth(),   source.getHeight(), matrix, true);


  return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);

}

1
sherin
public void setCameraPicOrientation(){
        int rotate = 0;
        try {
            File imageFile = new File(mCurrentPhotoPath);
            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);
        int targetW = 640;
        int targetH = 640;

        /* Get the size of the image */
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
        int photoW = bmOptions.outWidth;
        int photoH = bmOptions.outHeight;

        /* Figure out which way needs to be reduced less */
        int scaleFactor = 1;
        if ((targetW > 0) || (targetH > 0)) {
            scaleFactor = Math.min(photoW/targetW, photoH/targetH);
        }

        /* Set bitmap options to scale the image decode target */
        bmOptions.inJustDecodeBounds = false;
        bmOptions.inSampleSize = scaleFactor;
        bmOptions.inPurgeable = true;

        /* Decode the JPEG file into a Bitmap */
        Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
        bitmap= Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
            /* Associate the Bitmap to the ImageView */
      imageView.setImageBitmap(bitmap);
    }

J'espère que ça va aider !! Merci

1
Dear S

deux solutions à une ligne utilisant Picasso et la bibliothèque de plané

Après avoir passé beaucoup de temps avec beaucoup de solutions au problème de rotation d’image, j’ai finalement trouvé deux solutions simples. Nous n'avons pas besoin de faire des travaux supplémentaires. Picasso et Glide constituent une bibliothèque très puissante pour la gestion des images dans votre application. Il lira les données EXIF ​​des images et effectuera une rotation automatique des images.

Utilisation de la bibliothèque de glissement https://github.com/bumptech/glide

Glide.with(this).load("http url or sdcard url").into(imgageView);

Utilisation de la bibliothèque Picasso https://github.com/square/picasso

Picasso.with(context).load("http url or sdcard url").into(imageView);
0
Vigneswaran A
    public static  int mOrientation =  1;

    OrientationEventListener myOrientationEventListener;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.takephoto);

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);


        myOrientationEventListener
        = new OrientationEventListener(getApplicationContext()) {

            @Override
            public void onOrientationChanged(int o) {
                // TODO Auto-generated method stub
                if(!isTablet(getApplicationContext()))
                {
                    if(o<=285 && o>=80)
                        mOrientation = 2;
                    else
                        mOrientation = 1;
                }
                else
                {
                    if(o<=285 && o>=80)
                        mOrientation = 1;
                    else
                        mOrientation = 2;
                }

            }
        };

        myOrientationEventListener.enable();

    }



    public static boolean isTablet(Context context) {
        return (context.getResources().getConfiguration().screenLayout
                & Configuration.SCREENLAYOUT_SIZE_MASK)
                >= Configuration.SCREENLAYOUT_SIZE_LARGE;
    }

}

J'espère que cela aidera.Merci!

0
jagdish

Essayez ceci dans le rappel surfaceChanged:

Camera.Parameters parameters=mCamera.getParameters();
if(this.getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){
    parameters.setRotation(90);
}else{
    parameters.setRotation(0);
}
mCamera.setParameters(parameters);
0
Manavendher

Juste rencontrer le même problème ici, l'extrait de code ci-dessous fonctionne pour moi:

private static final String[] CONTENT_ORIENTATION = new String[] {
        MediaStore.Images.ImageColumns.ORIENTATION
};

static int getExifOrientation(ContentResolver contentResolver, Uri uri) {
    Cursor cursor = null;

    try {
        cursor = contentResolver.query(uri, CONTENT_ORIENTATION, null, null, null);
        if (cursor == null || !cursor.moveToFirst()) {
            return 0;
        }
        return cursor.getInt(0);
    } catch (RuntimeException ignored) {
        // If the orientation column doesn't exist, assume no rotation.
        return 0;
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
}

espérons que cela aide :)

0
Cloud Chen