Preview, Capture & Record ▸ Auto Focus, Flash… ▸ No RAW support ▸ Difícil de implementar custom features (HDR, Burst, etc) ▸ No hay controles manuales (aperture, shutter speed)
de API Level 21 ▸ DSLR ▸ Total re-work (Camera1 es deprecada en API 21) ▸ On-device post processing (HDR, Focus Stacking) ▸ RAW support ▸ Manual exposure and shutter speed ▸ Mejor manejo de Multi-core CPU & GPU ▸ HAL update
CameraDevice: cámara conectada al dispositivo ▸ CameraManager: servicio para obtener un CameraDevice ▸ CameraCaptureSession: ▸ configura los outputs para CameraDevice ▸ se encarga de el manejo de requests ▸ CaptureResult: resultado de una ImageCapture request
96O 1.33 1280 X 720 1.77 800 X 480 1.66 720 X 480 1.5 640 X 480 1.33 576 X 432 1.33 480 X 320 1.5 384 X 288 1.33 352 X 288 1.22 320 X 240 1.33 CAMERA2 StreamConfigurationMap.getOutputSizes(SurfaceTexture.class)
new TextureView.SurfaceTextureListener() { @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { //SETEO OUTPUTS //INICIO LA CAMARA } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { return false; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) { } }; 2) DECLARO UN LISTENER PARA EL SURFACEVIEW
for (String cameraId : cameraManager.getCameraIdList()) { CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId); //We are interested in the back camera only if (CameraCharacteristics.LENS_FACING_FRONT == cameraCharacteristics. get(CameraCharacteristics.LENS_FACING)) { continue; } StreamConfigurationMap streamConfigurationMap = cameraCharacteristics. get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); } 3) CONFIGURAMOS LOS OUTPUTS 1/2
new CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice camera) { mCameraDevice = camera; createCameraPreviewSession(); } @Override public void onDisconnected(CameraDevice camera) { camera.close(); mCameraDevice = null; } @Override public void onError(CameraDevice camera, int error) { camera.close(); mCameraDevice = null; } }; 6) DEFINIMOS UN LISTENER PARA EL INICIO DE LA CAMARA
set up a CaptureRequest.Builder with the output Surface. mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); mPreviewRequestBuilder.addTarget(previewSurface); mCameraDevice.createCaptureSession(Arrays.asList(previewSurface), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession session) { // The camera is already closed if (null == mCameraDevice) { return; } // When the session is ready, we start displaying the preview. mCaptureSession = session; try { // Auto focus should be continuous for camera preview. mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); // Flash is automatically enabled when necessary. mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); mPreviewRequest = mPreviewRequestBuilder.build(); //We tell the camera to start the preview mCaptureSession.setRepeatingRequest(mPreviewRequest, mSessionCaptureCallback, null); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onConfigureFailed(CameraCaptureSession session) { } }, null); 8) CREAMOS LA SESION DE PREVIEW 2/2
onResume() { super.onResume(); startBackgroundThread(); // When the screen is turned off and turned back on, the SurfaceTexture is already // available, and "onSurfaceTextureAvailable" will not be called. In that case, we can open // a camera and start preview from here (otherwise, we wait until the surface is ready in // the SurfaceTextureListener). if (mTextureView.isAvailable()) { openCamera(mTextureView.getWidth(), mTextureView.getHeight()); } else { mTextureView.setSurfaceTextureListener(mSurfaceTextureListener); } } @Override public void onPause() { closeCamera(); super.onPause(); } 9) MANEJAMOS LOS RECURSOS DE LA CAMARA EN EL CICLO DE VIDA DEL FRAGMENT/ACTIVITY
captures, we use the largest available size. Size largest = Collections.max( Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)), new CompareSizesByArea()); mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(), ImageFormat.JPEG, /*maxImages*/2); mImageReader.setOnImageAvailableListener( mOnImageAvailableListener, mBackgroundHandler); 1) CREAMOS UN IMAGE READER
= new ImageReader.OnImageAvailableListener() { @Override public void onImageAvailable(ImageReader reader) { mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage(), mFile)); } }; 2) CREAMOS UN LISTENER PARA EL IMAGE READER
try { // Tell #mCaptureCallback to wait for the lock. mState = STATE_WAITING_LOCK; // This is how to tell the camera to lock focus. mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START); //Notify capture session that the builder has change mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } 3) BLOQUEAMOS EL FOCO
L Developer Preview - Camera2 API ▸ Android Camera2 API by Huyen Tue Dao Android Camera2 API by Huyen Tue Dao ▸ Camera 2 API by Mobile Application Tutorials ▸ https://github.com/googlesamples/android- Camera2Basic ▸ developer.android.com