Problema con la orientación personalizada de la imagen de Android

Escribí una actividad de cámara personalizada para manejar algunos problemas que he estado teniendo con ciertos dispositivos de Android cuando llamo captura de imagen intencional. El usuario puede seleccionar guardar la imagen o simplemente utilizar los datos devueltos de la OnPictureTakenCallback .

El problema que estoy teniendo es mostrar la imagen correctamente con respecto a la orientación que se tomó. SetRequestedOrientation la actividad que se muestra en el retrato llamando a SetRequestedOrientation .

¿Cómo puedo saber la correcta orientación de la cámara cuando el usuario tomó la foto? El usuario podría tomar la foto a una rotación de 90 (retrato).

He intentado usar getRotation() en la pantalla predeterminada del gestor de ventanas, pero con la configuración de la orientación solicitada al retrato que sólo devuelve Surface.ROTATION_0 .

Actualización: Para aclarar mi otro problema, ¿cómo podría determinar la orientación de sólo los datos de byte[] en la devolución de llamada de imagen si el usuario no para guardar la imagen?

Actualización: Después de probar las respuestas a continuación con este código todo lo que estoy recibiendo es ExifInterface.ORIENTATION_NORMAL. También he cambiado mi código para guardar el archivo devuelto de la cámara, ya que no estoy seguro de que hay una manera fácil de determinar la orientación con sólo tener los datos de byte[] .

  private PictureCallback mPicture = new PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { File directory = new File(android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_PICTURES), "MyApp"); if(!directory.exists()) { if(!directory.mkdirs()) { Log.d("CAMERA", "Unable to create directory to save photos."); return; } } File file = new File(directory.getPath() + file.separator + "IMG_" + SimpleDateFormat.getDateTimeInstance().toString() + ".jpg"); FileOutputStream fos = new FileOutputStream(file); fos.write(data); fos.close(); ExifInterface exif = new ExifInterface(file.getCanonicalPath()); int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); int rotate = 0; switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: rotate = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: rotate = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: rotate = 270; break; case default: break; } } }; 

Por lo que se enfrentan a algún problema con la orientación de la cámara.

Este enlace muestra una aplicación de ejemplo de una actividad de captura de cámara simple: http://labs.makemachine.net/2010/03/simple-android-photo-capture/

Tal vez deberías intentar arreglar la orientación haciendo algo como esto:

  ExifInterface exif = new ExifInterface(_path); int exifOrientation = exif.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); int rotate = 0; switch (exifOrientation) { case ExifInterface.ORIENTATION_ROTATE_90: rotate = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: rotate = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: rotate = 270; break; } if (rotate != 0) { int w = bitmap.getWidth(); int h = bitmap.getHeight(); // Setting pre rotate Matrix mtx = new Matrix(); mtx.preRotate(rotate); // Rotating Bitmap & convert to ARGB_8888, required by tess bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false); bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); } 

Necesitará leer los Metadatos del JPEG original para verificar la orientación en la que se tomó la fotografía.

 ExifInterface exif = new ExifInterface(SourceFileName); String exifOrientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION); 

Fuente: ¿Cómo determinar la orientación de la imagen sin ExifInterface?

Edit: Respondiendo a la edición, ¿ha intentado utilizar el método getCameraInfo () que está disponible con el objeto Camera pasado en la devolución de llamada? ¿Tiene la información que necesita?

Fuente: http://developer.android.com/reference/android/hardware/Camera.html

Eliminar el setRequestedOrientation() permite obtener getWindowManager().getDefaultDisplay().getRotation() para dar la rotación correcta. Supongo que la configuración de la orientación solicitada impide que la actividad se vuelva a dibujar cuando la configuración cambia, por lo que el dispositivo no sabe que ningún tipo de rotación ha cambiado. Mi único problema ahora es cambiar de modo de paisaje en 0 grados de orientación a modo horizontal 180 grados de rotación no se dispara esto:

 @Override public void onConfigurationChanged(Configuration newconfig) { super.onConfigurationChanged(newconfig); } 
 public void surfaceCreated(SurfaceHolder holder) { try { mCamera.setPreviewDisplay(holder); Camera.Parameters parameters = mCamera.getParameters(); if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) { parameters.set("orientation", "portrait"); <----THis gets the job done!!! // For Android Version 2.2 and above mCamera.setDisplayOrientation(90); // For Android Version 2.0 and above parameters.setRotation(90); } // End Effects for Android Version 2.0 and higher mCamera.setParameters(parameters); } catch (IOException exception) { mCamera.release(); } } 
  • ¿Cómo registrar un oyente para el cambio de orientación?
  • Comportamiento extraño de las medidas del campo magnético mientras gira el dispositivo
  • ¿Qué significa este Android Lint: "Orientación errónea?"
  • Evento del dispositivo Android onConfigurationChanged no controla la orientación
  • Cómo obtener el ancho de ventana correcto en el cambio de orientación para dispositivos Android, tabletas y móviles
  • Android: Problemas al calcular la orientación del dispositivo
  • Orientación de la pantalla de Android al sensor
  • ¿Cómo puedo proporcionar soporte de orientación para tablet solo en android?
  • ConfigChanges = "orientation" no se activa en Galaxy Nexus
  • ¿Cómo puedo asegurar la correcta orientación de reproducción del video grabado?
  • Android: orientación de la vista previa de la cámara en modo vertical
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.