Мой предварительный просмотр камеры растянут и сжат. Как я могу решить эту проблему?

1

(Я уже читал другие ответы на подобные вопросы, но они мне не помогли). Я новичок в API Android Camera 2 и пытаюсь создать собственную камеру. Все работает нормально, но предварительный просмотр растягивается, когда телефон находится в портретном режиме, и он сдавливается, когда телефон находится в ландшафтном режиме. Итак, как я могу решить мою проблему?

Здесь есть код, который может содержать ошибку.

private void setUpCameraOutputs(int width, int height) {

    try {
        CameraCharacteristics characteristics = this.cameraManager.getCameraCharacteristics(this.cameraId);

        StreamConfigurationMap map = characteristics.get(
            CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
        if (map != null) {
            this.imageReader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 2);
            this.imageReader.setOnImageAvailableListener(
                this.imageReaderListener,
                this.backgroundHandler);

        Point displaySize = new Point();

        this.getWindowManager().getDefaultDisplay().getSize(displaySize);
        int maxPreviewWidth = displaySize.x;
        int maxPreviewHeight = displaySize.y;

        if (MAX_PREVIEW_WIDTH < maxPreviewWidth) {
            maxPreviewWidth = MAX_PREVIEW_WIDTH;
        }

        if (MAX_PREVIEW_HEIGHT < maxPreviewHeight) {
            maxPreviewHeight = MAX_PREVIEW_HEIGHT;
        }

        //Viene selezionata la risoluzione ideale per l'anteprima
        this.previewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
                width, height, maxPreviewWidth, maxPreviewHeight);
    }
} catch (CameraAccessException e) {
    e.printStackTrace();
} catch (NullPointerException e) {
    //L'eccezione è lanciata quando le Camera2API sono usate,
    //ma non sono supportate dal dispositivo
    this.showToast("Camera2 API not supported on this device");
}

}

В этом методе я нахожу лучшее разрешение для предварительного просмотра

private static Size chooseOptimalSize(Size[] choices, int 
    textureViewWidth, int textureViewHeight,
                                      int maxWidth, int maxHeight) {
    //Raccoglie tutte le risoluzioni grandi almeno quanto la superficie di anteprima
    List<Size> bigEnough = new ArrayList<>();
    //Raccoglie tutte le risoluzioni più piccole della superficie di anteprima
    List<Size> notBigEnough = new ArrayList<>();

    //int w = aspectRatio.getWidth();
    int w = maxWidth;
    //int h = aspectRatio.getHeight();
    int h = maxHeight;
    for (Size option : choices) {
        if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight)
            if (option.getHeight() == option.getWidth() * h / w) {
                if (option.getWidth() >= textureViewWidth && option.getHeight() >= textureViewHeight) {
                    bigEnough.add(option);
                } else {
                    notBigEnough.add(option);
                }
            }
    }

    //Pick the smallest of those big enoughPrende la risoluzione minima tra quelle grandi abbastanza.
    //Se non ce ne sono di grandi abbastanza prende quella più grande tra quelle non
    //abbastanza grandi
    if (bigEnough.size() > 0) {
        return Collections.min(bigEnough, new CompareSizesByArea());
    } else if (notBigEnough.size() > 0) {
        return Collections.max(notBigEnough, new CompareSizesByArea());
    } else {
        Log.e("Camera2", "Couldn't find any suitable preview size");
        return choices[0];
    }
}
Теги:
android-camera2

2 ответа

0

Вы должны взглянуть на официальный образец Android Camera2 от Google: https://github.com/googlesamples/android-Camera2Basic

В частности, то, что вы пытаетесь достичь, в основном достигается с помощью класса AutoFitTextureView и метода chooseOptimalSize в файле Camera2BasicFragment, здесь фрагмент:

private static Size chooseOptimalSize(Size[] choices, int textureViewWidth,
        int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {

    // Collect the supported resolutions that are at least as big as the preview Surface
    List<Size> bigEnough = new ArrayList<>();
    // Collect the supported resolutions that are smaller than the preview Surface
    List<Size> notBigEnough = new ArrayList<>();
    int w = aspectRatio.getWidth();
    int h = aspectRatio.getHeight();
    for (Size option : choices) {
        if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight &&
                option.getHeight() == option.getWidth() * h / w) {
            if (option.getWidth() >= textureViewWidth &&
                option.getHeight() >= textureViewHeight) {
                bigEnough.add(option);
            } else {
                notBigEnough.add(option);
            }
        }
    }

    // Pick the smallest of those big enough. If there is no one big enough, pick the
    // largest of those not big enough.
    if (bigEnough.size() > 0) {
        return Collections.min(bigEnough, new CompareSizesByArea());
    } else if (notBigEnough.size() > 0) {
        return Collections.max(notBigEnough, new CompareSizesByArea());
    } else {
        Log.e(TAG, "Couldn't find any suitable preview size");
        return choices[0];
    }
}

Начало работы с Android Camera2 API может быть довольно сложным. Помимо официальной документации и вышеупомянутого официального образца, есть также несколько (надеюсь) полезных постов в блоге, таких как:

0

Размер предварительного просмотра должен соответствовать соотношению сторон поверхности, которую вы используете для его отображения. Образец Camera2 использует класс-оболочку AutoFitTextureView, который помогает изменить форму представления так, чтобы он соответствовал размеру предварительного просмотра, но копирование его в ваш проект может легко пойти не так, потому что это зависит от тонких нюансов инфлятора.

Для простоты установите размер вашего TextureView равным 1600px на 900px, и this.previewSize 1920 на 1080.

  • 0
    Я пытался, но это не сработало.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню