Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capture picture without preview using camera2 API

Tags:

What I want to achieve is capturing a picture without showing the preview, sending directly the output to an ImageReader. I have used the Camera2Basic example as a starting point. However, the callback of my ImageReader is never called, hence no image is sent to its Surface. Do I really need to display a preview first?

This is the camera code, which is ordered following the flow of the asynchronous callbacks:

private ImageReader imageReader; private Handler backgroundHandler; private HandlerThread backgroundThread; private String cameraId; private CameraDevice cameraDevice; private CameraCaptureSession cameraCaptureSession;     @Override     public void onCreate() {         setupCamera2();     }      private void setupCamera2() {         CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);          try {              for (String cameraId : manager.getCameraIdList()) {             CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);              if (characteristics.get(CameraCharacteristics.LENS_FACING) != CameraCharacteristics.LENS_FACING_FRONT) {                 continue;             }              this.cameraId = cameraId;              int[] picSize = Settings.getPictureSize();             int picWidth = picSize[0];             int picHeight = picSize[1];              imageReader = ImageReader.newInstance(picWidth, picHeight, ImageFormat.JPEG, 2);             imageReader.setOnImageAvailableListener(onImageAvailableListener, backgroundHandler);             }          } catch (CameraAccessException | NullPointerException e) {             e.printStackTrace();         }     }       private void openCamera2() {         CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);         try {              manager.openCamera(cameraId, cameraStateCallback, backgroundHandler);          } catch (CameraAccessException e) {             e.printStackTrace();         }     }        private final CameraDevice.StateCallback cameraStateCallback = new CameraDevice.StateCallback() {         @Override         public void onOpened(CameraDevice device) {             cameraDevice = device;             createCameraCaptureSession();         }          @Override         public void onDisconnected(CameraDevice cameraDevice) {}          @Override         public void onError(CameraDevice cameraDevice, int error) {}     };        private void createCaptureSession() {         List<Surface> outputSurfaces = new LinkedList<>();         outputSurfaces.add(imageReader.getSurface());          try {              cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {                 @Override                 public void onConfigured(CameraCaptureSession session) {                     cameraCaptureSession = session;                 }                  @Override                 public void onConfigureFailed(CameraCaptureSession session) {}             }, null);          } catch (CameraAccessException e) {             e.printStackTrace();         }     }       private final ImageReader.OnImageAvailableListener onImageAvailableListener = new ImageReader.OnImageAvailableListener() {         @Override         public void onImageAvailable(ImageReader reader) {             createCaptureRequest();         }     };       private void createCaptureRequest() {         try {              CaptureRequest.Builder requestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);             requestBuilder.addTarget(imageReader.getSurface());              // Focus             requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);              // Orientation             int rotation = windowManager.getDefaultDisplay().getRotation();             requestBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));              cameraCaptureSession.capture(requestBuilder.build(), camera2Callback, null);          } catch (CameraAccessException e) {             e.printStackTrace();         }     } 
like image 955
Alessandro Roaro Avatar asked Jan 17 '15 19:01

Alessandro Roaro


People also ask

Is Camera2 deprecated?

camera2 API for new applications. This class was deprecated in API level 21. We recommend using the new android.

What is Level 3 Camera2 API?

Full: These devices support all of the major capabilities of Camera API2 and must use Camera HAL 3.2 or higher and Android 5.0 or higher. Level_3: These devices support YUV reprocessing and RAW image capture, along with additional output stream configurations on top of full Camera2 API support.

What is Camera2 API?

Camera2 is the latest low-level Android camera package and replaces the deprecated Camera class. Camera2 provides in-depth controls for complex use cases, but requires you to manage device-specific configurations.

Should I use CameraX?

For new apps, we recommend starting with CameraX. It provides a consistent, easy-to-use API that works across the vast majority of Android devices, with backward-compatibility to Android 5.0 (API level 21).


1 Answers

You should capture photos in "onConfigured" function but not onImageAvailable.

public void onConfigured(CameraCaptureSession session) {             cameraCaptureSession = session;             createCaptureRequest();         } 

In this function "onImageAvailable",you should save images,

Image image = mImageReader.acquireLatestImage(); ByteBuffer buffer = image.getPlanes()[0].getBuffer(); byte[] bytes = new byte[buffer.remaining()]; buffer.get(bytes); try {     save(bytes, file); } catch (IOException e) {     e.printStackTrace(); } image.close(); 

"onImageAvailable" function will be invoked after session.capture() .

like image 191
yydcdut Avatar answered Sep 26 '22 22:09

yydcdut