Tomar una foto lo más rápido posible con la API de la cámara en Android

Guión:

Necesito tomar una foto lo más rápido posible y guardarla en la tarjeta SD. Sería fantástico si pudiera hacerlo en unos 0,2 segundos, tanto tomar la foto y guardarla.

Lo que hice hasta ahora:

Como de costumbre, he creado un SurfaceView para manejar la vista previa de la cámara e inicializado el objeto de la cámara. La calidad de la imagen no necesita ser muy alta, por eso no estoy usando la mayor resolución posible y tampoco se requiere autofoco. Establecer los parámetros como este:

Parameters parameters = camera.getParameters(); parameters.set("jpeg-quality", 70); parameters.setPictureFormat(ImageFormat.JPEG); List<Camera.Size> sizes = parameters.getSupportedPictureSizes(); Size size = sizes.get(Integer.valueOf((sizes.size()-1)/2)); //choose a medium resolution parameters.setPictureSize(size.width, size.height); camera.setParameters(parameters); camera.setDisplayOrientation(90); List<Size> sizes2 = parameters.getSupportedPreviewSizes(); Size size2 = sizes.get(0); parameters.setPreviewSize(size2.width, size2.height); camera.setPreviewDisplay(holder); camera.startPreview(); 

Ahorro la imagen a la tarjeta del SD muy simple con:

 PictureCallback handlePictureStorage = new PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { FileOutputStream outStream = null; try { outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis())); outStream.write(data); outStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { } } }; 

Después de hacer algunas pruebas, en mi Galaxy Nexus, el resultado se ve así:

  • Ajuste del tamaño de la imagen a: wigth = 1600 height = 1200
  • Calidad de JPEG: 70, Formato de imagen JPEG
  • El fuego toma la foto en: 00: 13: 23.603
  • Comience a guardar imágenes en la tarjeta SD en: 00: 13: 23.956
  • Imagen de ahorro finalizada en la tarjeta SD: 00: 13: 23.990

Esto es casi 0.4 segundos. ¿Hay una manera de ajustar los parámetros de la cámara aún más para ganar una velocidad más rápida? La resolución está bien, la calidad de la imagen también. Sé que hay aplicaciones en el mercado que tienen 30 imágenes por segundo, pero creo que utilizan el almacenamiento en búfer para lograr esa velocidad. Sin embargo, como usted puede ver el mayor tiempo se pierde con la toma de la imagen en lugar de guardarlo en la tarjeta. Sería genial si pudiera ajustar esto un poco más.

Después de hacer un poco de pruebas con múltiples parámetros, la conclusión es que no queda mucho por hacer. Estos son algunos de los parámetros que he configurado:

  //set color efects to none cameraParameters.setColorEffect(Camera.Parameters.EFFECT_NONE); //set antibanding to none if (cameraParameters.getAntibanding() != null) { cameraParameters.setAntibanding(Camera.Parameters.ANTIBANDING_OFF); } // set white ballance if (cameraParameters.getWhiteBalance() != null) { cameraParameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT); } //set flash if (cameraParameters.getFlashMode() != null) { cameraParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); } //set zoom if (cameraParameters.isZoomSupported()) { cameraParameters.setZoom(0); } //set focus mode cameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY); 

Sin embargo, la mejor idea es obtener la lista completa de cadenas de parámetros soportados por la cámara, y tratar de ajustarlos. Para obtener la cadena, utilice el método flatten de Camera.Parameters – http://developer.android.com/reference/android/hardware/Camera.Parameters.html#flatten ()

Pero para obtener imágenes muy rápido, tuve que usar la vista previa con búfer, y para cada fotograma tomado, trate de guardarlo en sd-tarjeta en un hilo. La calidad de la imagen no es fantástica, pero es un comienzo.

Si la calidad no importa, tal vez usted podría mirar en el uso de algo que no sea JPEG y comparar tiempos de ejecución: http://developer.android.com/reference/android/graphics/ImageFormat.html

  • Android: El tamaño de la vista previa de la cámara admitida es incorrecto
  • Android: hilo deteniéndose intermitentemente
  • Android Vista vs SurfaceView vs GLSurfaceView para la aplicación de dibujo 2D con Zoomable interfaz de usuario
  • Android: toma fotos sin vista previa
  • Comprensión de los conceptos de lienzo y superficie
  • Android, lienzo: ¿Cómo puedo borrar (eliminar contenidos de) un lienzo (= bitmaps), que viven en una surfaceView?
  • Uso de surfaceView para capturar un video
  • Android Surfaceview Hilos y fugas de memoria
  • Obtener información de GPU en Android sin SurfaceView
  • ¿Por qué onTouchEvent de SurfaceView llamado unos segundos retrasados?
  • Android: dibujo en un nuevo lienzo
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.