【问题标题】:How to take multiple images using CameraX?如何使用 CameraX 拍摄多张图像?
【发布时间】:2020-08-08 14:29:58
【问题描述】:

我的用例是一次拍摄两张图像。第一个为 2 倍缩放,第二个为 1 倍缩放级别。另外,我想将图像保存到文件中。

我的想法是以 2 倍变焦拍摄第一张图像,并在保存图像时将变焦级别设置为 1 倍,并在镜头变焦到 1 倍变焦级别时拍摄第二张图像。

但是,当我拍摄第一张图片时,预览会停留在第一张图片上,并且从设置 1 倍缩放回调永远不会发生。

这就是我创建捕获用例的方式。

private void createImageCaptureUseCases() {
    ImageCapture imageCapture1 = new ImageCapture.Builder()
        .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
        .build();

    ImageCapture imageCapture2 = new ImageCapture.Builder()
        .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
        .build();

    imageCaptureUseCases.clear();
    imageCaptureUseCases.add(imageCapture1);
    imageCaptureUseCases.add(imageCapture2);

这是我第一次启动相机会话的方式。

ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(getContext());

cameraProviderFuture.addListener(() -> {
    try {
        cameraProvider = cameraProviderFuture.get();
        preview = new Preview.Builder().build();

        cameraSelector = new CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build();

        Camera camera = cameraProvider.bindToLifecycle(
            ((LifecycleOwner) this),
            cameraSelector,
            preview,
            imageCapture);

        camera.getCameraControl().setZoomRatio(2f);

        preview.setSurfaceProvider(previewView.createSurfaceProvider(camera.getCameraInfo()));
    } catch (InterruptedException | ExecutionException e) {}
}, ContextCompat.getMainExecutor(getContext()));

这就是调用捕获图像的方式。

private void captureImage(ImageCapture imageCapture) {

    File pictureFile = ImageUtils.createImageFile(getActivity());
    ImageCapture.OutputFileOptions options = new 
        ImageCapture.OutputFileOptions.Builder(pictureFile).build();

    final Activity activity = getActivity();

    imageCapture.takePicture(options, ContextCompat.getMainExecutor(activity),
        new ImageCapture.OnImageSavedCallback() {

            @Override
            public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults){
                Log.i("my tag", "image Saved: " + pictureFile.getAbsolutePath());

                int index = imageCaptureUseCases.indexOf(imageCapture);
                cameraProvider.unbind(imageCapture);
                if (index < imageCaptureUseCases.size() - 1) {
                    Camera camera = cameraProvider.bindToLifecycle(
                    (LifecycleOwner) activity,
                    cameraSelector,
                    imageCaptureUseCases.get(index + 1));

                    ListenableFuture future = camera.getCameraControl().setZoomRatio(1f);
                    future.addListener(() -> captureImage(imageCaptureUseCases.get(index + 1)),
                                    ContextCompat.getMainExecutor(activity));
                } else {
                    createImageCaptureUseCases();
                    cameraProvider.unbindAll();
                    Camera camera = cameraProvider.bindToLifecycle(
                        (LifecycleOwner) activity,
                        cameraSelector,
                        preview,
                        imageCaptureUseCases.get(0));

                    camera.getCameraControl().setZoomRatio(2f);
                }
            }

            @Override
            public void onError(@NonNull ImageCaptureException exception) {
                Log.i("my tag", "image save error: " + pictureFile.getAbsolutePath());
            }
    });
}

【问题讨论】:

    标签: android android-camera android-camerax


    【解决方案1】:
    • 您不需要多个ImageCapture 实例来捕获具有2 个缩放比例的图像,您可以使用相同的实例,ImageCapture 处理拍照并保存/提供它,与诸如此类的参数无关作为缩放比例。

    • 查看您的代码示例,您似乎在第二次尝试捕获图像(使用不同的缩放比例)时没有绑定Preview 用例。这可以解释为什么您的预览在第一次图像捕获后卡住了。请记住,ImageCapture 用例不能单独绑定,它必须与至少 1 个 PreviewImageAnalysis 用例绑定。

    以下是捕获 2 张图像的示例,每张图像具有不同的缩放比例。代码包含一些重复,并且都在 1 块中,所以它肯定可以改进。

        private fun setUpCamera() {
           val mainExecutor = ContextCompat.getMainExecutor(this)
           val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
           cameraProviderFuture.addListener(Runnable {
              // Wait for the camera provider to be retrieved
              val cameraProvider = cameraProviderFuture.get()
    
              // Build your use cases
              val preview = Preview.Builder().build()
              val imageCapture = ImageCapture.Builder().build()
    
              // Get a camera selector to use
              val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
    
              // Bind the use cases to a lifecycle
              val camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture)
    
              // Set the preview surface provider
    preview.setSurfaceProvider(previewView.createSurfaceProvider(camera.cameraInfo))
    
              // Set the zoom ratio for the first photo
              val cameraControl = camera.cameraControl
              cameraControl.setZoomRatio(1F)
    
              // When the previewView is clicked, take the photos
              previewView.setOnClickListener {
                 imageCapture.takePicture(createOutputFilesOptions(), mainExecutor, object : ImageCapture.OnImageSavedCallback {
                    override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
    
                       // First image captured and saved successfully
                       Log.d(TAG, "OnImageSavedCallback.onImageSaved: Image saved with zoom ratio 1F")
    
                       // Set a new zoom ratio for the second image capture
                       cameraControl.setZoomRatio(2F)
    
                       // Capture the second picture with a different zoom ratio
                       imageCapture.takePicture(createOutputFilesOptions(), mainExecutor, object : ImageCapture.OnImageSavedCallback {
                          override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
    
                             // Second image captured and saved successfully
                             Log.d(TAG, "OnImageSavedCallback.onImageSaved: Image saved with zoom ratio 2F")
                          }
    
                          override fun onError(exception: ImageCaptureException) {
                             Log.e(TAG, "OnImageSavedCallback.onError", exception)
                          }
                       })
                    }
    
                    override fun onError(exception: ImageCaptureException) {
                       Log.e(TAG, "OnImageSavedCallback.onError", exception)
                    }
                 })
              }
           }, mainExecutor)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多