Как сделать несколько снимков с помощью CameraX? - PullRequest
1 голос
/ 25 апреля 2020

Мой вариант использования - снимать два изображения одновременно. первый с 2-кратным увеличением и второй с 1-кратным увеличением. Кроме того, я хочу сохранить изображения в файлы.

Моя идея сделать это состояла в том, чтобы сделать первое изображение с 2-кратным увеличением, а когда изображение будет сохранено, установить уровень масштабирования 1x и сделать второе изображение, когда объектив увеличено до 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());
            }
    });
}

1 Ответ

0 голосов
/ 25 апреля 2020
  • Вам не нужно несколько ImageCapture экземпляров для захвата изображения с 2-кратным увеличением ios, вы можете использовать один и тот же экземпляр, ImageCapture обрабатывает снимок и сохраняет его / предоставляя он не имеет отношения к таким параметрам, как коэффициент масштабирования.

  • Глядя на пример кода, вы можете не связывать вариант использования Preview во второй раз, когда пытаетесь захватить изображение (с другим коэффициентом масштабирования). Это объясняет, почему ваш предварительный просмотр застревает после первого захвата изображения. Помните, что ImageCapture вариант использования не может быть привязан сам по себе, он должен быть связан как минимум с 1 Preview или ImageAnalysis сценарием использования.

Ниже приведен выборка для захвата 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)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...