Android cámara de pantalla completa – manteniendo la cámara seleccionada ratio

Estamos intentando construir algo similar a la pantalla de la cámara de Instagram . Permitir que el usuario tome fotos square . Mientras lo hace Ui debe ser capaz de permitir al usuario ver la cámara en modo de fullScreen completa. Queremos obligar al usuario a tomar una imagen en un modo de portrait

Obtener la relación posible de la cámara

Estamos calculando la best relación disponible de la camera por

  private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) { final double ASPECT_TOLERANCE = 0.1; double targetRatio = (double) h / w; if (sizes == null) { return null; } Camera.Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = h; for (Camera.Size size : sizes) { double ratio = (double) size.width / size.height; if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) { continue; } if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } if (optimalSize == null) { minDiff = Double.MAX_VALUE; for (Camera.Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } return optimalSize; } 

Hacerlo a pantalla completa.

 public FrameLayout setCameraLayout(int width, int height) { float newProportion = (float) width / (float) height; // Get the width of the screen int screenWidth = this.customCameraActivity.getWindowManager().getDefaultDisplay() .getWidth(); int screenHeight = this.customCameraActivity.getWindowManager().getDefaultDisplay() .getHeight(); float screenProportion = (float) screenWidth / (float) screenHeight; // Get the SurfaceView layout parameters ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)preview.getLayoutParams(); if (newProportion > screenProportion) { lp.width = screenWidth; lp.height = (int) ((float) screenWidth / newProportion); } else { lp.width = (int) (newProportion * (float) screenHeight); lp.height = screenHeight; } //calculate the amount that takes to make it full screen (in the `height` parameter) float propHeight = screenHeight / lp.height; //make it full screen( lp.width = (int)(lp.width * propHeight); lp.height = (int)(lp.height * propHeight); frameLayout.setLayoutParams(lp); return frameLayout; } 

SetCameraLayout llamadas

OnCreate de la Activity y después surfaceChanged

  @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if (getHolder().getSurface() == null) { return; } try { cameraManager.getCamera().stopPreview(); } catch (Exception e) { // tried to stop a non-existent preview } try { Camera.Parameters cameraSettings = cameraManager.getCamera().getParameters(); cameraSettings.setPreviewSize(mPreviewSize.width, mPreviewSize.height); this.cameraView.setCameraLayout(mPreviewSize.width, mPreviewSize.height); cameraManager.getCamera().setParameters(cameraSettings); cameraManager.getCamera().setPreviewDisplay(holder); cameraManager.getCamera().startPreview(); } catch (Exception e) { Log.d(TAG, "Error starting camera preview: " + e.getMessage()); } } 

Gol

Vista previa de la cámara en pantalla completa en el teléfono.

El problema

Ahora estamos recibiendo la vista previa sin distorsión que es BUENO! Y tiene la misma height que el phone , así que también es bueno! . ¡Pero! El ancho de la preview es mayor que el phone width del phone width (por supuesto) por lo que resulta que el centro de la cámara no está en el centro del teléfono. Posibles soluciones que hemos pensado:

  1. move el diseño a la izquierda a la posición negativa para hacer que el centro de vista previa en el centro de la pantalla.
  2. crop el diseño y dibujar sólo el centro de la new preview que debe ser visible a las phone screens

¿Alguna idea de cómo superar este problema?

¡Muchas gracias! 🙂

2 Solutions collect form web for “Android cámara de pantalla completa – manteniendo la cámara seleccionada ratio”

Conseguí centrar exitosamente la inspección previo fijando la gravedad de SurfaceView:

 FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(wid, hei); lp.gravity = Gravity.CENTER; mSv.setLayoutParams(lp); 

El fragmento de código se toma de aquí , y le invitamos a usar el código si tiene la paciencia para descifrarlo. Creo que estaba resolviendo problemas similares (rotación de vista previa, distorsión, ajuste / relleno)

Buena suerte.

Si entiendo de los fragmentos de código, vuelve a instanciar la cámara cada vez que el usuario cambia de orientación o gira la cámara. ¿Hay alguna razón para hacerlo?

¿Por qué no restringir la vista previa sólo al retrato y tener una vista superpuesta que gira? Estoy bastante seguro de que es lo que hacen los demás (Instagram, Snapchat, etc.). Voy a editar con un ejemplo de esto, si puedo encontrarlo.

  • No se pudo escribir el volcado de núcleo. Minidumps no están habilitados de forma predeterminada en las versiones de cliente de Windows en Eclipse
  • ¿Pausar y reanudar AsyncTasks? (Androide)
  • AudioSystem cerrando aleatoriamente mientras se funden 2 objetos MediaPlayer
  • Uso de la gramática JSGF en lugar del modelo de lenguaje DMP (use -jsgf en lugar de -lm) en CMU Sphinx (pocketsphinx)
  • Diferencia, en minutos, entre dos fechas
  • Fragmento no se actualizará después de la notificación de apertura
  • Alternativa para String.join en Android?
  • ¿Cómo decirle a ProGuard que ofusque métodos y nombres de clase?
  • Creación de GIF está tomando tanto tiempo en Android
  • Android: el método i (String, String) no está definido para el tipo Log
  • Uso de Xtend para el desarrollo de Android (de nuevo)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.