При добавлении предварительного просмотра в приложение используйте PreviewView — View , которое можно обрезать, масштабировать и поворачивать для правильного отображения.
Предварительный просмотр изображения передается на поверхность внутри PreviewView , когда камера становится активной.
Используйте предварительный просмотр
Реализация предварительного просмотра для CameraX с помощью PreviewView включает следующие шаги, которые описаны в следующих разделах:
- При необходимости настройте
CameraXConfig.Provider. - Добавьте
PreviewViewв свой макет. - Запросите
ProcessCameraProvider. - При создании
Viewпроверьте наличиеProcessCameraProvider. - Выберите камеру и привяжите ее жизненный цикл и варианты использования.
Использование 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 выполните следующие действия:
- Создайте
Preview. - Укажите желаемую опцию
LensFacingкамеры. - Привяжите выбранную камеру и все варианты использования к жизненному циклу.
- Подключите
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
Процесс показа видео состоит из следующих этапов:
- Масштабируйте видео:
- Для типов масштабирования
FIT_*масштабируйте видео с помощьюmin(dst.width/src.width, dst.height/src.height). - Для типов масштабирования
FILL_*масштабируйте видео с помощьюmax(dst.width/src.width, dst.height/src.height).
- Для типов масштабирования
- Совместите масштабированное видео с целевым
PreviewView:- Для
FIT_CENTER/FILL_CENTERвыровняйте масштабированное видео по центру и целевой объектPreviewView. - Для
FIT_START/FILL_STARTвыровняйте масштабированное видео и целевой объектPreviewViewотносительно верхнего левого угла каждого из них. - Для
FIT_END/FILL_ENDвыровняйте масштабированное видео и целевой объектPreviewViewотносительно правого нижнего угла каждого из них.
- Для
Например, вот исходное видео 640x480 и целевое PreviewView 1920x1080:

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

Процесс работает следующим образом:
- Масштабируйте видеокадр (сохраняя исходное соотношение сторон) с
min(1920/640, 1080/480) = 2.25чтобы получить промежуточный видеокадр размером 1440x1080. - Совместите видеокадр 1440x1080 с
PreviewView1920x1080.- Для
FIT_CENTERвыровняйте видеокадр по центру окнаPreviewView. Начальный и конечный столбцыPreviewViewразмером 240 пикселей пусты. - Для
FIT_STARTвыровняйте видеокадр по началу (верхнему левому углу) окнаPreviewView. Конечные столбцыPreviewViewразмером 480 пикселей пусты. - Для
FIT_ENDвыровняйте видеокадр по концу (правому нижнему углу) окнаPreviewView. Начальные столбцыPreviewViewразмером 480 пикселей пусты.
- Для
На следующем изображении показан процесс масштабирования FILL_START / FILL_CENTER / FILL_END :

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