0

我正在尝试使用来自 Google 的 camera2 和 ML-kit API 创建条形码扫描仪。我终于设法让预览工作,但不知道如何获取图片本身并将其传递给 ML-kit API。

我试过使用图像阅读器类,但不知何故没有调用 onImageAvailable 类。

这是代码:

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) {}
}
4

1 回答 1

0

好像忘了补充:

mPreviewRequestBuilder.addTarget(mImageReaderSurface);

此外,相机在 5 帧后冻结。为了帮助解决这个问题,请参考Camera2 ImageReader freezes repeating capture request

于 2018-08-11T14:39:52.453 回答