Включить предварительный просмотр во время сеанса захвата на Camera2

Я создаю приложение камеры на основе Camera2, но сохраняемое мной изображение не соответствует последнему, которое я видел на моем виде поверхности. Кажется, что сеанс предварительного просмотра работает, но когда я запрашиваю захват, новый запрос останавливает предварительный просмотр и захватывает изображение. Вид поверхности застывает на последней картинке, что создает разрыв между моментом, когда я нажимаю кнопку спуска затвора (запуск предварительного просмотра и захват запроса) и onCaptureCompleted из запроса захвата.

Вот сеанс предварительного просмотра

private void createCameraPreviewSession() {

    try {

        SurfaceTexture texture = mTextureView.getSurfaceTexture();
        assert texture != null;

        texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());

        Log.d(TAG, "here is the width of texture" + mPreviewSize.getWidth());
        Log.d(TAG, "here is the height of texture" +mPreviewSize.getHeight());

        Surface surface = new Surface(texture);

        mPreviewRequestBuilder
                = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        mPreviewRequestBuilder.addTarget(surface);

        mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
                new CameraCaptureSession.StateCallback() {

                    @Override
                    public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                        if (null == mCameraDevice) {
                            return;
                        }

                        mCaptureSession = cameraCaptureSession;
                        try {
                            mPreviewRequest = mPreviewRequestBuilder.build();
                            mCaptureSession.setRepeatingRequest(mPreviewRequest,
                                    mCaptureCallback, mBackgroundHandler);
                        } catch (CameraAccessException e) {
                            e.printStackTrace();
                        }
                    }

                    @Override
                    public void onConfigureFailed(
                            @NonNull CameraCaptureSession cameraCaptureSession) {
                        showToast("Failed");
                    }
                }, null
        );
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

mCaptureCallback определяется следующим образом:

private CameraCaptureSession.CaptureCallback mCaptureCallback = new CameraCaptureSession.CaptureCallback () {

    private void process(CaptureResult result) {
        switch (mState) {
            case STATE_PREVIEW:
                break;

            case STATE_CAPTURE:
                mState = STATE_PREVIEW;
                capturePicture();
                break;
        }
    }

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

        process(partialResult);
    }


    @Override
    public void onCaptureCompleted(@NonNull CameraCaptureSession session,
                                   @NonNull CaptureRequest request,
                                   @NonNull TotalCaptureResult result) {
        TotalCaptureResult iResult = result;
        Log.d(TAG, "Frame on Completed: "+result.getFrameNumber());
        process(result);
    }
}

Что происходит, так это то, что я повторяю предварительный просмотр, и он работает. процесс используется только для того, чтобы он продолжал работать, и ничего не происходило, пока для mState не было установлено значение CAPTURE.

Он настроен на захват, когда мы нажимаем кнопку спуска затвора. Когда нажимаю на кнопку, я звоню:

private void takePicture(){
        try {
            mFile = ImageSaver.generateNewFileImage();
            mState = STATE_CAPTURE;
            mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
                    mBackgroundHandler);
        } catch (CameraAccessException e) {
            Log.e(TAG,"Camera exception",e);
        }
    }

Затем я вызываю CapturePicture, поскольку mState находится в Capture, как определено в mCaptureCallback

private void capturePicture() {
    mTakePictureRunnable = new Runnable() {
        @Override
        public void run() {
            takePictureNow();
        }
    };
    mBackgroundHandler.post(mTakePictureRunnable);
}

TakePicutreNow определяется

private void takePictureNow() {

    Log.d(TAG, "Running captureStillPicture");

    try {
        if (null == mCameraDevice) {
            return;
        }
        // This is the CaptureRequest.Builder that we use to take a picture.
        final CaptureRequest.Builder captureBuilder =
                mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);

        captureBuilder.addTarget(mImageReader.getSurface());

        SurfaceTexture texture = mTextureView.getSurfaceTexture();
        assert texture != null;

        texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());

        Log.d(TAG, "here is the width of texture" + mPreviewSize.getWidth());
        Log.d(TAG, "here is the height of texture" + mPreviewSize.getHeight());

        Surface surface = new Surface(texture);
        captureBuilder.addTarget(surface);


        // Orientation
        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));

        //Location if needed
        boolean Location_Saved = CameraSettings.Instance().getBoolean(CameraSettings.SAVE_LOCATION,
                getResources().getBoolean(R.bool.action_camera_settings_dflt_location));

        if(Location_Saved == true) {
            captureBuilder.set(CaptureRequest.JPEG_GPS_LOCATION, mLocationManager.getCurrentLocation());
        } else {
            captureBuilder.set(CaptureRequest.JPEG_GPS_LOCATION, null);
        }


        CameraCaptureSession.CaptureCallback CaptureCallback
                = new CameraCaptureSession.CaptureCallback() {

            @Override
            public void onCaptureStarted(@NonNull CameraCaptureSession session,
                                         @NonNull CaptureRequest request,
                                         @NonNull long timestamp,
                                         @NonNull long framenumber) {
                playShutterSound();
                showShutterAnimation();

            }

            @Override
            public void onCaptureCompleted(@NonNull CameraCaptureSession session,
                                           @NonNull CaptureRequest request,
                                           @NonNull TotalCaptureResult result) {
                Log.d(TAG, mFile.toString());
                mState = STATE_PREVIEW;
            }
        };

        mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);
        mCaptureSession.stopRepeating();

    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

Этот процесс работает, но у меня есть задержка между печатью и сохранением изображений, и последнее изображение, которое я видел на экране из предварительного просмотра, не совсем то же самое, что и сохраненное, если я двигаюсь быстро.

Кажется, что захват не обновляет поверхность, а поверхность отображается только тогда, когда мы были в предварительном просмотре

Есть идеи посмотреть, что я сохраню? Спасибо


person Seb    schedule 03.01.2016    source источник


Ответы (1)


Поверхность замерзнет, ​​когда вы сделаете изображение, это может быть не то изображение, которое сохраняется. Если вы по-прежнему хотите отображать предварительный просмотр камеры на экране, вам просто нужно перезапустить предварительный просмотр камеры, вызвав функцию, которую вы использовали для создания предварительного просмотра в первый раз.

person Aravind jayan    schedule 25.07.2019
comment
Camera2 API Preview растягивается, как исправить эту проблему? - person Erum; 09.01.2020