Problème d'orientation de la caméra sur Android

je construis une application qui utilise la caméra 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 onActivityResult() méthode, j'utilise BitmapFactory.decodeStream() pour capter l'image.

quand J'exécute mon application sur Nexus one, il fonctionne bien. Mais quand je cours 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 (enregistrer sur la carte SD)) il tourne toujours à 90 degrés.

image preview after shot real image on SD card

aperçu de l'Image après coup --------- Réelle de l'image sur la carte SD

  • Capture avec le mode paysage, tout va bien.

Image preview after shot Real image on SD card

aperçu de l'Image après coup --------- Réelle de l'image sur la carte SD

98
demandé sur Alex Cohn 2011-05-20 12:07:21

14 réponses

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

certains appareils tournent l'image avant de la sauvegarder, tandis que d'autres ajoutent simplement la balise d'orientation dans les données exif de la photo.

je recommande de vérifier les données exif de la photo et de chercher en particulier pour

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 assurez-vous où est le problème, mais cela devrait certainement vous mettre sur le droit chemin!

50
répondu ramz 2011-05-25 12:21:27

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 retournée est dans le paysage, donc je la tourne de 90 degrés.

espère que cela aidera quelqu'un d'autre avec cette question.

26
répondu 2012-06-01 05:22:40

il y a deux choses nécessaires:

  1. l'aperçu de la caméra doit être le même que votre rotation. Mettez ceci par camera.setDisplayOrientation(result);

  2. enregistrez l'image capturée en preview de votre appareil photo. 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);
    

Espère que ça aide.

21
répondu Tran Khanh Tung 2014-09-08 09:53:07
            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
répondu vineet pal 2014-01-14 12:40:39

une autre option est de faire tourner le bitmap dans l'écran résultat 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);
7
répondu Emilio 2011-09-14 09:50:49

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
répondu 135 2015-03-18 16:25:33

plus de vérification des données exif de la photo. Allez-y doucement avec Glide .

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

Ex: Planer.avec(contexte).charge(uri).dans (imageview);

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

2
répondu S.Prapagorn 2015-10-11 12:31:01

Essayez par ici : statique Uri image_uri; image statique 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
répondu sherin 2014-04-16 10:41:37
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);
    }

Espère que cela va vous aider!! Merci

1
répondu Dear S 2017-01-23 06:15:23
    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
répondu jagdish 2014-06-05 06:42:04

juste rencontrer le même problème ici, le code snippet 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
répondu Cloud Chen 2014-09-18 08:08:26

Essayer dans la surfaceChanged rappel:

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
répondu Manavendher 2015-01-26 10:49:09

deux Une ligne de solutions à l'aide de Picasso et de la glisse de la bibliothèque

après avoir passé beaucoup de temps avec beaucoup de solutions pour le 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 sont une bibliothèque très puissante pour manipuler des images dans votre application inclut. Il lira les données image EXIF et fera tourner les images.

utilisant la bibliothèque de plané 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
répondu Vigneswaran A 2017-12-04 10:41:40

le code est fonctionnel pour paysage et portrait @frontCameraID = variable a obtenu la méthode classique pour montrer à la caméra voulu

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    if(holder.getSurface() == null) {
        return;
    }
    try{
        camera.stopPreview();
    } catch (Exception e){
    }

    try{

        int orientation = getDisplayOrientation(frontCameraID);

        Camera.Parameters parameters = camera.getParameters();
        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        }

        parameters.setRotation(rotationPicture);
        camera.setParameters(parameters);
        camera.setDisplayOrientation(orientation);
        camera.startPreview();

    } catch (Exception e) {
        Log.i("ERROR", "Camera error changed: " + e.getMessage());
    }
}

méthode pour obtenir l'orientation y rotation pour enregistrer l'orientation de l'image et de l'affichage @résultat = orientation sur l'aperçu de la caméra @rotationPicture = rotation nécessaire pour sauvegarder l'image correctement

private int getDisplayOrientation(int cameraId) {

    android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
    android.hardware.Camera.getCameraInfo(cameraId, info);
    int rotation = ((Activity) context).getWindowManager().getDefaultDisplay().getRotation();
    int degrees = 0;
    switch (rotation) {
        case Surface.ROTATION_0: degrees = 0; break;
        case Surface.ROTATION_90: degrees = 90; break;
        case Surface.ROTATION_180: degrees = 180; break;
        case Surface.ROTATION_270: degrees = 270; break;
    }

    int result;
    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        result = (info.orientation + degrees) % 360;
        result = (360 - result) % 360;
        rotationPicture = (360 - result) % 360;
    } else {
        result = (info.orientation - degrees + 360) % 360;
        rotationPicture = result;
    }

    return result;
}

Quelqu'un a une question sur le code, s'il vous plaît dites-moi.

-1
répondu Alex Zaraos 2015-12-16 22:18:52