Android Camera2 getPreviewFrame

Я пытаюсь получить рамку камеры в режиме предварительного просмотра. Я запускаю образец проекта из github https://github.com/googlesamples/android-Camera2Basic

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

Вот код:

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

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

                //HERE, HOW CAN I RETRIEVE THE CURRENT FRAME?

                break;
            }
            case STATE_WAITING_LOCK: {
               ...
                break;
            }
            case STATE_WAITING_PRECAPTURE: {
             ...
                break;
            }
            case STATE_WAITING_NON_PRECAPTURE: {
             ...
                break;
            }
        }
    }

Еще одна вещь, которую я пытался получить в кадре, - установить mImageReader.setOnImageAvailableListener. Я ожидал, что сможет получить обратный вызов frameImageAvailable, но onImageAvailable никогда не вызывается. onPreviewFrame - мой собственный метод, мне нужно передать ему текущий кадр.

  mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(), ImageFormat.JPEG, /*maxImages*/2);
  mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);

  private final ImageReader.OnImageAvailableListener mOnImageAvailableListener  = new ImageReader.OnImageAvailableListener() {

    @Override
    public void onImageAvailable(ImageReader reader) {
        mTextureView.onPreviewFrame(reader.acquireNextImage().getPlanes([0].getBuffer().array());
    }

};

Что я делаю неправильно? Спасибо.

Ответ 1

Обратный вызов OnImageAvailableListener.onImageAvailable никогда не вызывается, когда доступен кадр предварительного просмотра, поскольку CaptureRequest, который был отправлен методу CameraCaptureSession.setRepeatingRequest(), не отображал ImageReader Surface в качестве конечной цели.

Вы определяете, какой вывод Surface (буферов исходного байта, по существу) вы хотите, чтобы данные каждого захвата включались при отправке запроса на камеру. Поэтому, чтобы получить "кадры предварительного просмотра", чтобы вызвать обратный вызов onImageAvailable(), а затем отправить его вашему методу onPreviewFrame(), просто добавьте строку:

mPreviewRequestBuilder.addTarget(mImageReader.getSurface());

Эта строка может идти, например, после другой аналогичной строки, которая добавляет SurfaceTexture Surface к тому же построителю запросов.

Обратите внимание, что это отправит каждый кадр предварительного просмотра вашей функции, а также "выходные кадры" из кнопки захвата. Вы можете захотеть, чтобы какой-либо код в обратном вызове onImageAvailable() различался.