0

I'm trying to create a barcode scanner with the camera2 and ML-kit API from Google. I've finally managed to get the preview working, but have no idea how to get the picture itself and pass that on to the ML-kit API.

I've tried using the image reader class, but somehow the onImageAvailable class is not being called.

Here is the code:

import ...

public class barcodeScannerActivity extends AppCompatActivity
        implements OnRequestPermissionsResultCallback {
    CameraManager mCameraManager;
    SurfaceView mSurfaceViewPreview;
    Surface mSurfacePreview;
    CaptureRequest.Builder mPreviewRequestBuilder;
    CaptureRequest mPreviewRequest;
    List<Surface> mSurfaceList;
    ImageReader mImageReader;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_barcode_scanner);

        FirebaseVisionBarcodeDetectorOptions options =
                new FirebaseVisionBarcodeDetectorOptions.Builder()
                        .setBarcodeFormats(
                                FirebaseVisionBarcode.FORMAT_EAN_13,
                                FirebaseVisionBarcode.FORMAT_EAN_8,
                                FirebaseVisionBarcode.FORMAT_UPC_A,
                                FirebaseVisionBarcode.FORMAT_UPC_E)
                        .build();

        FirebaseVisionBarcodeDetector detector = FirebaseVision.getInstance().
                getVisionBarcodeDetector(options);

        initCamera();
    }

    private void initCamera() {
        try {
            Log.d("debug", "camera initiated...");

            int permission = ContextCompat.checkSelfPermission(getApplicationContext(),
                    android.Manifest.permission.CAMERA);
            int granted = PackageManager.PERMISSION_GRANTED;

            if(permission == granted) {
                mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
                String[] cameraIdList = mCameraManager.getCameraIdList();
                if(cameraIdList.length == 0) {
                    throw new Exception("No camera found", null);
                }

                String backFacingCameraID = getBackFacingCameraID(cameraIdList);
                if(backFacingCameraID != null) {
                    mSurfaceList = new ArrayList<>();
                    mSurfaceViewPreview = findViewById(R.id.barcodeScanner);
                    mSurfacePreview = mSurfaceViewPreview.getHolder().getSurface();
                    mSurfaceList.add(mSurfacePreview);

                    mCameraManager.openCamera(backFacingCameraID, cameraCallback, null);
                } else {
                    //show error message that no backfacing camera is found.
                }
            } else {
                ActivityCompat.requestPermissions(this,
                        new String[] {android.Manifest.permission.CAMERA}, 0);
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    private CameraDevice.StateCallback cameraCallback = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(@NonNull CameraDevice cameraDevice) {
            try {
                mPreviewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                mPreviewRequestBuilder.addTarget(mSurfacePreview);
                mPreviewRequest = mPreviewRequestBuilder.build();

                cameraDevice.createCaptureSession(mSurfaceList, stateCallback, null);
            } catch(Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onDisconnected(@NonNull CameraDevice cameraDevice) {}

        @Override
        public void onError(@NonNull CameraDevice cameraDevice, int i) {}
    };

    private CameraCaptureSession.StateCallback stateCallback = new CameraCaptureSession.StateCallback() {
        @Override
        public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
            try {
                cameraCaptureSession.setRepeatingRequest(mPreviewRequest, captureCallback ,null);
            } catch(Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {}
    };

    private CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {
        @Override
        public void onCaptureStarted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, long timestamp, long frameNumber) {
            super.onCaptureStarted(session, request, timestamp, frameNumber);
        }

        @Override
        public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
            super.onCaptureProgressed(session, request, partialResult);
        }

        @Override
        public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
            super.onCaptureCompleted(session, request, result);

            Log.d("debug", String.valueOf(result.getPartialResults()));
        }

        @Override
        public void onCaptureFailed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure) {
            super.onCaptureFailed(session, request, failure);
        }
    };

    private String getBackFacingCameraID(String[] cameraIdList) {
        String backFacingCameraID = null;

        try {
            for(String cameraID:cameraIdList) {
                CameraCharacteristics characteristics =
                        mCameraManager.getCameraCharacteristics(cameraID);
                if(characteristics.get(CameraCharacteristics.LENS_FACING) == 1) {
                    backFacingCameraID = cameraID;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return backFacingCameraID;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        initCamera();
    }

    public void backButton(View view) {}
}
Ibrahim Ulukaya
  • 12,767
  • 1
  • 33
  • 36
B.Cakir
  • 567
  • 1
  • 5
  • 19
  • please refer this [link](https://github.com/googlesamples/android-Camera2Basic/blob/master/Application/src/main/java/com/example/android/camera2basic/Camera2BasicFragment.java) – Nirav Bhavsar Aug 11 '18 at 13:02
  • @NiravBhavsar I've read that document 3 times already, are you sure that it shows how to take a picture while using "setRepeatingRequest"? – B.Cakir Aug 11 '18 at 13:04
  • this [SO Question](https://stackoverflow.com/questions/28003186/capture-picture-without-preview-using-camera2-api) might help you please check. – Nirav Bhavsar Aug 11 '18 at 13:08
  • @NiravBhavsar, didn't really help. But thanks for the suggestion. – B.Cakir Aug 11 '18 at 13:27

1 Answers1

0

It seems that I forgot to add:

mPreviewRequestBuilder.addTarget(mImageReaderSurface);

Also, the camera froze after 5 frames. To help this, please refer to Camera2 ImageReader freezes repeating capture request

B.Cakir
  • 567
  • 1
  • 5
  • 19