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! 🙂

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.

  • ¿Cómo animar el ancho y la altura de un Layout?
  • FIleNotFound abierto falló: EACCES (Permiso denegado)
  • Convertir matriz de bytes a Base64 String en android
  • Cómo encontrar el seguimiento de pila en Eclipse con Android
  • Implementación del menú de opciones una vez para varias actividades
  • Evento onClick no está desencadenando | Androide
  • Cómo almacenar Lista de dispositivos adb en la red en php array
  • N-Puzzle pseudo-aleatorio barajar?
  • Apache Commons IO en Android
  • ArrayList como variable global
  • Android: TextView automáticamente truncar y reemplazar los últimos 3 caracteres de String
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.