Как заморозить/заблокировать предварительный просмотр камеры Android X с обновлениями вспышки при съемке?

#java #android #camera #android-camerax

Вопрос:

Я внедряю камеру X. Проблема, с которой я сталкиваюсь, заключается в реализации механизма блокировки/замораживания предварительного просмотра камеры при съемке изображения. В настоящее время я реализовал обходной путь, но он не работает хорошо, если во время съемки горит вспышка. Я получаю кадр из previewView (предварительного просмотра) previewView.getBitmap() , как и перед захватом изображения, а затем отображаю в captureImage (просмотр изображений). Но стоп-кадр не показывает обновления вспышки. Мой текущий код приведен ниже

 
    private void capturePhoto() {

        showProgress(true);

        // Get the Information to be used amp; stored with Image
        ContentValues contentValues = getImageSaveInfo();

        Uri externalUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

        ImageCapture.OutputFileOptions options = new ImageCapture.OutputFileOptions
                .Builder(getContentResolver(), externalUri, contentValues)
                .build();


        // Play the Capture Sound when a picture is captured.
        playCameraShutterSound();

        // Display current frame From Preview in ImageView.
        freezePreview(true);

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

                    @Override
                    public void onImageSaved(@NonNull ImageCapture.OutputFileResults results) {

                        ToastUtility.successToast(getApplicationContext(),
                                "Photo Capture Successfully");

                        // Update Last Taken Image View with new Image

                        getLastTakenImage();

                        if (results.getSavedUri() != null) {

                            Log.d(TAG, "Image Saved At -> "   results.getSavedUri().toString());

                        }

                        showProgress(false);
                        freezePreview(false);

                    }

                    @Override
                    public void onError(@NonNull ImageCaptureException exception) {

                        ToastUtility.errorToast(getApplicationContext(),
                                "Photo Couldn't Capture");

                        Log.d(TAG, "Image Capture Error -> "   exception.getMessage());

                        showProgress(false);
                        freezePreview(false);

                    }
                });

    }

 
 
    private void freezePreview(boolean value) {

        if (value) {

            Bitmap bitmap = mainBinding.previewView.getBitmap();

            Glide.with(getApplicationContext())
                    .load(bitmap).into(mainBinding.captureImage);

            mainBinding.captureImage.setVisibility(View.VISIBLE);

            mainBinding.previewView.setVisibility(View.INVISIBLE);

        } else {

            mainBinding.previewView.setVisibility(View.VISIBLE);

            mainBinding.captureImage.setVisibility(View.INVISIBLE);

        }

    }
 

Ответ №1:

Вспышка срабатывает в какой-то момент после takePicture() вызова, в CameraX для нее нет обратного вызова, поэтому нет прямого способа узнать, когда она сработает.

Вместо этого вы можете использовать взаимодействие camera2 для косвенной проверки состояния вспышки. Вы можете добавить обратный вызов сеанса в конфигурацию ImageCapture, а затем внутри обратного onCaptureCompleted вызова проверить , запущено ли состояние вспышки общего результата.

 // Override onCaptureCompleted to check for the flash state
CameraCaptureSession.CaptureCallback sessionCaptureCallback = //... ;

// Initialize an ImageCapture builder
ImageCapture.Builder configBuilder = new ImageCapture.Builder();

// Add the session CaptureCallback to it
new Camera2Interop.Extender<>(configBuilder)
    .setSessionCaptureCallback(sessionCaptureCallback);

// Build the ImageCapture use case
ImageCapture useCase = configBuilder.build();