Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


La cámara android setDisplayOrientation (90) falla en diferentes dispositivos

Tengo un problema con mi aplicación de cámara. La actividad de la cámara está en modo retrato.

camera.setDisplayOrientation(90); 

Según los diferentes puestos en SO, esto funcionará bien en modo retrato.

Pero nunca funciona bien con diferentes dispositivos.El problema es, vista previa rotar 90 grados izquierda o derecha.En Htc está bien. Pero con las series de galaxias no funciona.

Alguien puede ayudarme ?

  • Android: la vista previa de la cámara es lateral
  • Android: fija la orientación de la pantalla sólo para una página (diferencia telefónica)
  • Android: diseño alternativo xml para el modo horizontal
  • Android onConfigurationChanged () no se llama en Actividad
  • OnCreate no se llama cuando la pantalla gira - Android
  • Android Compass orientación en poco fiable (filtro de paso bajo)
  • Cambiar la orientación de la pantalla - Android 3.2 en VirtualBox
  • Orientación del diseño en código
  • 4 Solutions collect form web for “La cámara android setDisplayOrientation (90) falla en diferentes dispositivos”

    He dado esta respuesta a una pregunta similar, pero como usted dice que fue en un dispositivo HTC. Recomiendo que añada puntos de interrupción al código de rotación y examine las variables mientras gira físicamente el dispositivo. Esto puede ayudar a identificar lo que es diferente con los modelos de Galaxy.

    Establezca orientación y previsualización de diferentes maneras, use como requisito:

    Primeras maneras:

      public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if (isPreviewRunning) { mCamera.stopPreview(); } Parameters parameters = mCamera.getParameters(); Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay(); if(display.getRotation() == Surface.ROTATION_0) { parameters.setPreviewSize(height, width); mCamera.setDisplayOrientation(90); } if(display.getRotation() == Surface.ROTATION_90) { parameters.setPreviewSize(width, height); } if(display.getRotation() == Surface.ROTATION_180) { parameters.setPreviewSize(height, width); } if(display.getRotation() == Surface.ROTATION_270) { parameters.setPreviewSize(width, height); mCamera.setDisplayOrientation(180); } mCamera.setParameters(parameters); previewCamera(); } 

    y

      public void previewCamera() { try { mCamera.setPreviewDisplay(mSurfaceHolder); mCamera.startPreview(); isPreviewRunning = true; } catch(Exception e) { Log.d(APP_CLASS, "Cannot start preview", e); } } 

    Segundos caminos:

      private Camera mCamera; private OrientationEventListener mOrientationEventListener; private int mOrientation = -1; private static final int ORIENTATION_PORTRAIT_NORMAL = 1; private static final int ORIENTATION_PORTRAIT_INVERTED = 2; private static final int ORIENTATION_LANDSCAPE_NORMAL = 3; private static final int ORIENTATION_LANDSCAPE_INVERTED = 4; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // force Landscape layout setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR | ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); /* Your other initialization code here */ } @Override protected void onResume() { super.onResume(); if (mOrientationEventListener == null) { mOrientationEventListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) { @Override public void onOrientationChanged(int orientation) { // determine our orientation based on sensor response int lastOrientation = mOrientation; if (orientation >= 315 || orientation < 45) { if (mOrientation != ORIENTATION_PORTRAIT_NORMAL) { mOrientation = ORIENTATION_PORTRAIT_NORMAL; } } else if (orientation < 315 && orientation >= 225) { if (mOrientation != ORIENTATION_LANDSCAPE_NORMAL) { mOrientation = ORIENTATION_LANDSCAPE_NORMAL; } } else if (orientation < 225 && orientation >= 135) { if (mOrientation != ORIENTATION_PORTRAIT_INVERTED) { mOrientation = ORIENTATION_PORTRAIT_INVERTED; } } else { // orientation <135 && orientation > 45 if (mOrientation != ORIENTATION_LANDSCAPE_INVERTED) { mOrientation = ORIENTATION_LANDSCAPE_INVERTED; } } if (lastOrientation != mOrientation) { changeRotation(mOrientation, lastOrientation); } } }; } if (mOrientationEventListener.canDetectOrientation()) { mOrientationEventListener.enable(); } } @Override protected void onPause() { super.onPause(); mOrientationEventListener.disable(); } /** * Performs required action to accommodate new orientation * @param orientation * @param lastOrientation */ private void changeRotation(int orientation, int lastOrientation) { switch (orientation) { case ORIENTATION_PORTRAIT_NORMAL: mSnapButton.setImageDrawable(getRotatedImage(android.R.drawable.ic_menu_camera, 270)); mBackButton.setImageDrawable(getRotatedImage(android.R.drawable.ic_menu_revert, 270)); Log.v("CameraActivity", "Orientation = 90"); break; case ORIENTATION_LANDSCAPE_NORMAL: mSnapButton.setImageResource(android.R.drawable.ic_menu_camera); mBackButton.setImageResource(android.R.drawable.ic_menu_revert); Log.v("CameraActivity", "Orientation = 0"); break; case ORIENTATION_PORTRAIT_INVERTED: mSnapButton.setImageDrawable(getRotatedImage(android.R.drawable.ic_menu_camera, 90)); mBackButton.setImageDrawable(getRotatedImage(android.R.drawable.ic_menu_revert, 90)); Log.v("CameraActivity", "Orientation = 270"); break; case ORIENTATION_LANDSCAPE_INVERTED: mSnapButton.setImageDrawable(getRotatedImage(android.R.drawable.ic_menu_camera, 180)); mBackButton.setImageDrawable(getRotatedImage(android.R.drawable.ic_menu_revert, 180)); Log.v("CameraActivity", "Orientation = 180"); break; } } /** * Rotates given Drawable * @param drawableId Drawable Id to rotate * @param degrees Rotate drawable by Degrees * @return Rotated Drawable */ private Drawable getRotatedImage(int drawableId, int degrees) { Bitmap original = BitmapFactory.decodeResource(getResources(), drawableId); Matrix matrix = new Matrix(); matrix.postRotate(degrees); Bitmap rotated = Bitmap.createBitmap(original, 0, 0, original.getWidth(), original.getHeight(), matrix, true); return new BitmapDrawable(rotated); } 

    Y luego en su PictureCallback establecer metadatos para indicar el nivel de rotación:

     private Camera.PictureCallback mJpegCallback = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { try { // Populate image metadata ContentValues image = new ContentValues(); // additional picture metadata image.put(Media.DISPLAY_NAME, [picture name]); image.put(Media.MIME_TYPE, "image/jpg"); image.put(Media.TITLE, [picture title]); image.put(Media.DESCRIPTION, [picture description]); image.put(Media.DATE_ADDED, [some time]); image.put(Media.DATE_TAKEN, [some time]); image.put(Media.DATE_MODIFIED, [some time]); // do not rotate image, just put rotation info in switch (mOrientation) { case ORIENTATION_PORTRAIT_NORMAL: image.put(Media.ORIENTATION, 90); break; case ORIENTATION_LANDSCAPE_NORMAL: image.put(Media.ORIENTATION, 0); break; case ORIENTATION_PORTRAIT_INVERTED: image.put(Media.ORIENTATION, 270); break; case ORIENTATION_LANDSCAPE_INVERTED: image.put(Media.ORIENTATION, 180); break; } // store the picture Uri uri = getContentResolver().insert( Media.EXTERNAL_CONTENT_URI, image); try { Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); OutputStream out = getContentResolver().openOutputStream( uri); boolean success = bitmap.compress( Bitmap.CompressFormat.JPEG, 75, out); out.close(); if (!success) { finish(); // image output failed without any error, // silently finish } 

    Ahora cuando los dispositivos basados ​​en el paisaje están apareciendo una comprobación adicional para que se requiere en OrientationEventListener.

      Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay(); if (display.getOrientation() == Surface.ROTATION_0) { // landscape oriented devices } else { // portrait oriented device } 

    Código completo (un poco despilfarrador por LC, pero demuestra fácilmente el enfoque)

      @Override public void onOrientationChanged(int orientation) { // determine our orientation based on sensor response int lastOrientation = mOrientation; Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay(); if (display.getOrientation() == Surface.ROTATION_0) { // landscape oriented devices if (orientation >= 315 || orientation < 45) { if (mOrientation != ORIENTATION_LANDSCAPE_NORMAL) { mOrientation = ORIENTATION_LANDSCAPE_NORMAL; } } else if (orientation < 315 && orientation >= 225) { if (mOrientation != ORIENTATION_PORTRAIT_INVERTED) { mOrientation = ORIENTATION_PORTRAIT_INVERTED; } } else if (orientation < 225 && orientation >= 135) { if (mOrientation != ORIENTATION_LANDSCAPE_INVERTED) { mOrientation = ORIENTATION_LANDSCAPE_INVERTED; } } else if (orientation <135 && orientation > 45) { if (mOrientation != ORIENTATION_PORTRAIT_NORMAL) { mOrientation = ORIENTATION_PORTRAIT_NORMAL; } } } else { // portrait oriented devices if (orientation >= 315 || orientation < 45) { if (mOrientation != ORIENTATION_PORTRAIT_NORMAL) { mOrientation = ORIENTATION_PORTRAIT_NORMAL; } } else if (orientation < 315 && orientation >= 225) { if (mOrientation != ORIENTATION_LANDSCAPE_NORMAL) { mOrientation = ORIENTATION_LANDSCAPE_NORMAL; } } else if (orientation < 225 && orientation >= 135) { if (mOrientation != ORIENTATION_LANDSCAPE_INVERTED) { mOrientation = ORIENTATION_LANDSCAPE_INVERTED; } } else if (orientation <135 && orientation > 45) { if (mOrientation != ORIENTATION_PORTRAIT_NORMAL) { mOrientation = ORIENTATION_PORTRAIT_NORMAL; } } } else { // portrait oriented devices if (orientation >= 315 || orientation < 45) { if (mOrientation != ORIENTATION_PORTRAIT_NORMAL) { mOrientation = ORIENTATION_PORTRAIT_NORMAL; } } else if (orientation < 315 && orientation >= 225) { if (mOrientation != ORIENTATION_LANDSCAPE_NORMAL) { mOrientation = ORIENTATION_LANDSCAPE_NORMAL; } } else if (orientation < 225 && orientation >= 135) { if (mOrientation != ORIENTATION_PORTRAIT_INVERTED) { mOrientation = ORIENTATION_PORTRAIT_INVERTED; } } else if (orientation <135 && orientation > 45) { if (mOrientation != ORIENTATION_LANDSCAPE_INVERTED) { mOrientation = ORIENTATION_LANDSCAPE_INVERTED; } } } if (lastOrientation != mOrientation) { changeRotation(mOrientation, lastOrientation); } } 

    Terceras maneras:

      private Bitmap adjustImageOrientation(Bitmap image) { ExifInterface exif; try { exif = new ExifInterface(picturePath); 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 = image.getWidth(); int h = image.getHeight(); // Setting pre rotate Matrix mtx = new Matrix(); mtx.preRotate(rotate); // Rotating Bitmap & convert to ARGB_8888, required by tess image = Bitmap.createBitmap(image, 0, 0, w, h, mtx, false); } } catch (IOException e) { return null; } return image.copy(Bitmap.Config.ARGB_8888, true); } 

    Compruebe si la opción "Rotación automática de pantalla" está marcada en el teléfono Ajustes (Ajustes> Desplegar o Pantalla – depende de la versión de Android).

    Simplemente publicar una nueva solución que funcionó para mí.

    Básicamente, puede obtener el valor de orientación de Camera.CameraInfo. Esto indicará los grados que necesitará usar en setDisplayOrientation para que la imagen se muestre correctamente. Cuando se utiliza la cámara de cara hacia atrás puede utilizar simplemente setDisplayOrientation con el valor recuperado, pero cuando se utiliza la cámara frente a frente que necesita para ajustar un poco como el sistema Android se voltea la imagen por lo que parece como un espejo.

    Debajo de código trabajado para mí y probado en 4 dispositivos diferentes, incluyendo un Nexus6 y Galaxy.

     Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); int cameraCount = Camera.getNumberOfCameras(); int camIdx = 0; // DO your logic to get front or back camera...or loop through all avaialable. Camera.getCameraInfo(camIdx, cameraInfo); try { mCamera = Camera.open(camIdx); // If using back camera then simply rotate what CameraInfo tells you. if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) mCamera.setDisplayOrientation(cameraInfo.orientation); else // If using front camera note that image might be flipped to give users the impresion the are looking at a mirror. mCamera.setDisplayOrientation( (360 - cameraInfo.orientation) % 360); } catch (Exception e) { e.printStackTrace(); } 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.