Problème d’orientation de la caméra dans Android

Je construis une application qui utilise une caméra pour prendre des photos. Voici mon code source pour ce 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 BitmapFactory.decodeStream() l’image.

Quand je lance mon application sur Nexus One, ça marche bien. Mais quand je cours sur Samsung Galaxy S ou HTC Inspire 4G, la direction de l’image est incorrecte.

  • Capture en mode portrait, l’image réelle (enregistrer sur la carte SD) tourne toujours à 90 degrés.

aperçu de l'image après le tirimage réelle sur la carte SD

Aperçu de l’image après le tir ——— Image réelle sur la carte SD

  • Capture en mode paysage, tout va bien.

Aperçu de l'image après le tirImage réelle sur la carte SD

Aperçu de l’image après le tir ——— Image réelle sur la carte SD

    Il y a pas mal de sujets et de problèmes similaires ici. Comme vous n’écrivez pas votre propre appareil photo, je pense que cela se résume à ceci:

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

    Je 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 Ssortingng exifOrientation = exif.getAtsortingbute(ExifInterface.TAG_ORIENTATION); 

    Étant donné que la photo s’affiche correctement dans votre application, je ne sais pas où est le problème, mais cela devrait certainement vous mettre sur la bonne voie!

    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()) { Masortingx masortingx = new Masortingx(); masortingx.postRotate(90); mBitmap = Bitmap.createBitmap(mBitmap , 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), masortingx, true); } } 

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

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

    Il y a deux choses à faire:

    1. L’aperçu de la caméra nécessite la même chose que votre rotation. Définissez ceci par camera.setDisplayOrientation(result);

    2. Enregistrez l’image capturée comme aperçu de votre appareil photo. Faites cela 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 cela pourra aider.

      int rotate = 0; try { File imageFile = new File(sourcepath); ExifInterface exif = new ExifInterface( imageFile.getAbsolutePath()); int orientation = exif.getAtsortingbuteInt( 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(); } Masortingx masortingx = new Masortingx(); masortingx.postRotate(rotate); bitmap = Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), masortingx, true); 

    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 Masortingx mtx = new Masortingx(); mtx.postRotate(90); // Rotating Bitmap Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, w, h, mtx, true); BitmapDrawable bmd = new BitmapDrawable(rotatedBMP); img.setImageDrawable(bmd); 

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

     private void rotateImage(final Ssortingng path) { Bitmap scaledBitmap = Bitmap.createScaledBitmap(Conasants.bm1, 1000, 700, true); Bitmap rotatedBitmap = null; try { ExifInterface ei = new ExifInterface(path); int orientation = ei.getAtsortingbuteInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); Masortingx masortingx = new Masortingx(); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: masortingx.postRotate(90); rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), masortingx, true); break; case ExifInterface.ORIENTATION_ROTATE_180: masortingx.postRotate(180); rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), masortingx, true); break; case ExifInterface.ORIENTATION_ROTATE_270: masortingx.postRotate(270); rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), masortingx, true); break; default: rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), masortingx, true); break; } } catch (Throwable e) { e.printStackTrace(); } cropImage.setImageBitmap(rotatedBitmap); rotatedBitmap = null; Conasants.bm1 = null; } 

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

    Google nous a présenté une bibliothèque Image Loader pour Android développée par bumptech sous le nom de Glide en tant que bibliothèque recommandée par Google. Il a été utilisé dans de nombreux projets open source Google, y compris l’application officielle Google I / O 2014.

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

    Pour plus d’informations: https://github.com/bumptech/glide

    Essayez de cette façon: statique Uri image_uri; bitmap 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.getAtsortingbuteInt(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) { Masortingx masortingx = new Masortingx(); masortingx.postRotate(angle); round_Image = source; round_Image = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), masortingx, true); return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), masortingx, true); 

    }

     public void setCameraPicOrientation(){ int rotate = 0; try { File imageFile = new File(mCurrentPhotoPath); ExifInterface exif = new ExifInterface( imageFile.getAbsolutePath()); int orientation = exif.getAtsortingbuteInt( 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(); } Masortingx masortingx = new Masortingx(); masortingx.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(), masortingx, true); /* Associate the Bitmap to the ImageView */ imageView.setImageBitmap(bitmap); } 

    J’espère que cela aidera !! Merci

      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 vous aidera. Merci!

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

     private static final Ssortingng[] CONTENT_ORIENTATION = new Ssortingng[] { 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(); } } } 

    J’espère que ça aide 🙂

    Essayez ceci dans le callback 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); 

    deux solutions en une ligne utilisant Picasso et la bibliothèque de glisse

    Après avoir passé beaucoup de temps avec beaucoup de solutions pour le problème de rotation des images, j’ai finalement trouvé deux solutions simples. Nous n’avons pas besoin de faire de travaux supplémentaires. Picasso et Glide sont une bibliothèque très puissante pour gérer les images de votre application. Il lit les données EXIF ​​de l’image et fait pivoter automatiquement les images.

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

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

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

     Picasso.with(context).load("http url or sdcard url").into(imageView); 

    Le code est fonctionnellement pour landscape et portrait @frontCameraID = variable a obtenu la méthode classique pour show camera

     @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 d’obtention de l’orientation et de la rotation pour enregistrer l’orientation de l’image et de l’affichage @result = orientation sur la vue de prévisualisation de la caméra

     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.