Реализация предварительного просмотра

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

Предварительный просмотр изображения передается на поверхность внутри 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 :

Котлин

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

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

Ява

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

public class MainActivity extends AppCompatActivity {
    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
    }
}

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

После запроса CameraProvider убедитесь, что его инициализация прошла успешно при создании представления. Следующий код показывает, как это сделать:

Котлин

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

Ява

cameraProviderFuture.addListener(() -> {
    try {
        ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
        bindPreview(cameraProvider);
    } catch (ExecutionException | InterruptedException e) {
        // No errors need to be handled for this Future.
        // This should never be reached.
    }
}, 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)
}

Ява

void bindPreview(@NonNull ProcessCameraProvider cameraProvider) {
    Preview preview = new Preview.Builder()
            .build();

    CameraSelector cameraSelector = new CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build();

    preview.setSurfaceProvider(previewView.getSurfaceProvider());

    Camera camera = cameraProvider.bindToLifecycle((LifecycleOwner)this, 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 относительно правого нижнего угла каждого из них.

Например, вот исходное видео 640x480 и целевое PreviewView 1920x1080:

Изображение, показывающее видео размером 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 чтобы получить промежуточный видеокадр размером 1440x1080.
  2. Совместите видеокадр 1440x1080 с PreviewView 1920x1080.
    • Для FIT_CENTER выровняйте видеокадр по центру окна PreviewView . Начальный и конечный столбцы PreviewView размером 240 пикселей пусты.
    • Для FIT_START выровняйте видеокадр по началу (верхнему левому углу) окна PreviewView . Конечные столбцы PreviewView размером 480 пикселей пусты.
    • Для FIT_END выровняйте видеокадр по концу (правому нижнему углу) окна PreviewView . Начальные столбцы PreviewView размером 480 пикселей пусты.

На следующем изображении показан процесс масштабирования FILL_START / FILL_CENTER / FILL_END :

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

Процесс работает следующим образом:

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

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

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

Кодлаб

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

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