Как реализовать предварительный просмотр

Добавляя предварительный просмотр в приложение, используйте PreviewView – это View, который можно обрезать, масштабировать и поворачивать для правильного отображения.

Когда камера становится активной, изображение с нее передается на поверхность внутри PreviewView.

Как использовать PreviewView

Чтобы реализовать предварительный просмотр для CameraX с помощью PreviewView, выполните следующие действия, которые описаны в следующих разделах:

  1. При необходимости настройте CameraXConfig.Provider.
  2. Добавьте PreviewView в макет.
  3. Запросите ProcessCameraProvider.
  4. При создании View проверьте ProcessCameraProvider.
  5. Выберите камеру и привяжите жизненный цикл и способы использования.

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

  • Создайте SurfaceTexture, чтобы задать TextureView и Preview.SurfaceProvider.
  • Получите SurfaceTexture из TextureView и задайте его в Preview.SurfaceProvider.
  • Возьмите Surface из SurfaceView и установите на Preview.SurfaceProvider.

В любом из этих случаев Preview прекращает передачу кадров на PreviewView.

Добавьте PreviewView в макет

Ниже приведен пример макета с элементом PreviewView.

<FrameLayout
    android:id="@+id/container">
        <androidx.camera.view.PreviewView
            android:id="@+id/previewView" />
</FrameLayout>

Запрос CameraProvider

В следующем примере кода показано, как запросить CameraProvider:

// import androidx.camera.lifecycle.ProcessCameraProvider
// import com.google.common.util.concurrent.ListenableFuture

class MainActivity : ComponentActivity() {
    private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        cameraProviderFuture = ProcessCameraProvider.getInstance(this)
    }
}

Проверьте доступность CameraProvider

После запроса CameraProvider убедитесь, что инициализация прошла успешно, когда представление создано. Ниже показано, как это сделать.

cameraProviderFuture.addListener(
    Runnable {
        val cameraProvider = cameraProviderFuture.get()
        bindPreview(cameraProvider)
    },
    ContextCompat.getMainExecutor(this)
)

Пример использования функции bindPreview приведен в следующем разделе.

Выберите камеру и привяжите жизненный цикл и способы использования

После того как вы создадите и подтвердите CameraProvider, выполните следующие действия:

  1. Создайте Preview.
  2. Выберите нужный вариант камеры LensFacing.
  3. Привяжите выбранную камеру и все варианты использования к жизненному циклу.
  4. Подключите Preview к PreviewView.

Пример кода:

fun bindPreview(cameraProvider: ProcessCameraProvider) {
    var preview: Preview = Preview.Builder()
        .build()

    var cameraSelector: CameraSelector = CameraSelector.Builder()
        .requireLensFacing(CameraSelector.LENS_FACING_BACK)
        .build()

    preview.setSurfaceProvider(previewView.getSurfaceProvider())

    var camera = cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, preview)
}

Обратите внимание, что bindToLifecycle() возвращает объект Camera. Подробнее о настройках камеры, таких как масштаб и экспозиция…

Вы завершили реализацию предварительного просмотра камеры. Создайте приложение и убедитесь, что предварительный просмотр работает так, как вы планировали.

Дополнительные элементы управления для PreviewView

В CameraX PreviewView есть дополнительные API для настройки таких свойств, как:

Режим реализации

PreviewView может использовать один из следующих режимов для рендеринга потока предварительного просмотра на целевом объекте View:

  • PERFORMANCE – режим по умолчанию. Для показа видеопотока PreviewView использует SurfaceView, но в некоторых случаях переключается на TextureView. SurfaceView имеет выделенную поверхность для рисования, которая с большей вероятностью будет реализована с аппаратным наложением с помощью внутреннего аппаратного компоновщика, особенно когда поверх видео предварительного просмотра нет других элементов пользовательского интерфейса (например, кнопок). При отрисовке с аппаратным оверлеем кадры видео не проходят через графический процессор, что может снизить энергопотребление и задержку.

  • COMPATIBLE. В этом режиме PreviewView использует TextureView, у которого, в отличие от SurfaceView, нет выделенной поверхности для рисования. В результате видео отображается со смешиванием. На этом этапе приложение может выполнять дополнительную обработку, например масштабирование и поворот видео без ограничений.

Используйте PreviewView.setImplementationMode(), чтобы выбрать режим реализации, подходящий для вашего приложения. Если режим по умолчанию PERFORMANCE не подходит для вашего приложения, вы можете задать режим COMPATIBLE, как показано в примере кода ниже.

// viewFinder is a PreviewView instance.
viewFinder.implementationMode = PreviewView.ImplementationMode.COMPATIBLE

Тип шкалы

Если разрешение видео в предварительном просмотре отличается от размеров целевого устройства PreviewView, видеоконтент необходимо подогнать под размер экрана, обрезав его или добавив черные полосы (сохранив исходное соотношение сторон). Для этого в PreviewView предусмотрены следующие ScaleTypes:

  • FIT_CENTER, FIT_START и FIT_END для кашетирования. Видеоконтент масштабируется (увеличивается или уменьшается) до максимально возможного размера, который может быть показан в целевом объекте PreviewView. Однако, хотя кадр видео виден полностью, часть экрана может быть пустой. В зависимости от выбранного типа масштабирования кадр видео выравнивается по центру, началу или концу целевого представления.

  • FILL_CENTER, FILL_START, FILL_END для кадрирования. Если соотношение сторон видео не равно PreviewView, то видна только часть контента, но видео заполняет весь экран PreviewView.

По умолчанию CameraX использует тип масштабирования FILL_CENTER. Используйте PreviewView.setScaleType(), чтобы задать тип масштабирования, наиболее подходящий для вашего приложения. В следующем примере кода задается тип масштабирования FIT_CENTER:

// viewFinder is a PreviewView instance.
viewFinder.scaleType = PreviewView.ScaleType.FIT_CENTER

Процесс показа видео состоит из следующих этапов:

  1. Чтобы изменить масштаб видео:
    • Для типов масштабирования FIT_* масштабируйте видео с помощью min(dst.width/src.width, dst.height/src.height).
    • Для типов масштабирования FILL_* масштабируйте видео с помощью max(dst.width/src.width, dst.height/src.height).
  2. Выровняйте масштабированное видео по целевому объекту PreviewView:
    • Для FIT_CENTER/FILL_CENTER выровняйте по центру масштабированное видео и целевой элемент PreviewView.
    • Для FIT_START/FILL_START выровняйте масштабированное видео и целевую область PreviewView по верхнему левому углу.
    • Для FIT_END/FILL_END выровняйте масштабированное видео и целевую область PreviewView по их правому нижнему углу.

Например, у вас есть исходное видео размером 640 x 480 и целевое видео размером 1920 x 1080. PreviewView

Изображение, на котором сравнивается видео с разрешением 640 x 480 и предварительный просмотр с разрешением 1920 x 1080

На изображении ниже показан процесс масштабирования FIT_START / FIT_CENTER / FIT_END.

Изображение, показывающее процесс масштабирования FIT_START, FIT_CENTER и FIT_END

Вот как это работает:

  1. Масштабируйте кадр видео (сохраняя исходное соотношение сторон) с помощью min(1920/640, 1080/480) = 2.25, чтобы получить промежуточный кадр видео размером 1440 x 1080.
  2. Выровняйте кадр видео 1440 x 1080 по кадру 1920 x 1080 PreviewView.
    • Для FIT_CENTER выровняйте кадр видео по центру окна PreviewView. Первые и последние 240 пикселей столбцов PreviewView должны быть пустыми.
    • Для FIT_START выровняйте кадр видео по началу (левому верхнему углу) окна PreviewView. Последние 480 пикселей столбцов PreviewView пустые.
    • Для FIT_END выровняйте кадр видео по концу (правому нижнему углу) окна PreviewView. Первые 480 пикселей столбцов PreviewView пустые.

На изображении ниже показан процесс масштабирования FILL_START / FILL_CENTER / FILL_END.

Изображение, показывающее процесс масштабирования FILL_START, FILL_CENTER и FILL_END

Вот как это работает:

  1. Масштабируйте кадр видео с помощью max(1920/640, 1080/480) = 3, чтобы получить промежуточный кадр видео размером 1920 x 1440 (что больше размера PreviewView).
  2. Кадрируйте видео 1920 x 1440, чтобы оно помещалось в окно PreviewView 1920 x 1080.
    • Для FILL_CENTER обрежьте видео 1920 x 1440 до 1920 x 1080, начиная от центра. Верхние и нижние 180 строк видео не видны.
    • Для FILL_START обрежьте видео с разрешением 1920 x 1440 до 1920 x 1080, начиная с начала. Нижние 360 строк видео не видны.
    • Для FILL_END обрежьте 1920 x 1080 с конца масштабированного видео 1920 x 1440. Верхние 360 строк видео не видны.

Дополнительные ресурсы

Чтобы узнать больше о CameraX, ознакомьтесь со следующими дополнительными ресурсами.

Практическая работа

  • Начало работы с CameraX
  • Пример кода

  • Примеры приложений CameraX