При добавлении предварительного просмотра в приложение используйте 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 с
PreviewView
1920x1080.- Для
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, чтобы он соответствовал окну
PreviewView
размером 1920x1080.- Для
FILL_CENTER
обрежьте 1920x1080 из центра масштабированного видео 1920x1440. Верхние и нижние 180 строк видео не видны. - Для
FILL_START
обрежьте 1920x1080 от начала масштабированного видео 1920x1440. Нижние 360 строк видео не видны. - Для
FILL_END
обрежьте 1920x1080 от конца масштабированного видео 1920x1440. Верхние 360 строк видео не видны.
- Для
Дополнительные ресурсы
Чтобы узнать больше о CameraX, см. следующие дополнительные ресурсы.