Dodając podgląd do aplikacji, użyj PreviewView, czyli View, który można przycinać, skalować i obracać, aby zapewnić prawidłowe wyświetlanie.
Gdy aparat jest aktywny, podgląd obrazu jest przesyłany strumieniowo na powierzchnię wewnątrz PreviewView.
Korzystanie z widoku PreviewView
Implementacja podglądu dla CameraX za pomocą PreviewView obejmuje te kroki, które zostały opisane w dalszych sekcjach:
- Opcjonalnie skonfiguruj
CameraXConfig.Provider. - Dodaj
PreviewViewdo układu. - Poproś o
ProcessCameraProvider. - Podczas tworzenia
Viewsprawdź, czy jestProcessCameraProvider. - Wybierz kamerę i powiąż cykl życia oraz przypadki użycia.
Korzystanie z usługi PreviewView wiąże się z pewnymi ograniczeniami. Gdy używasz PreviewView, nie możesz:
- Utwórz
SurfaceTexture, aby ustawićTextureViewiPreview.SurfaceProvider. - Pobierz
SurfaceTexturezTextureViewi ustaw wPreview.SurfaceProvider. - Pobierz
SurfacezSurfaceViewi ustaw go naPreview.SurfaceProvider.
Jeśli wystąpi którykolwiek z tych problemów, Preview przestanie przesyłać klatki do PreviewView.
Dodawanie PreviewView do układu
Poniższy przykład pokazuje element PreviewView w układzie:
<FrameLayout android:id="@+id/container"> <androidx.camera.view.PreviewView android:id="@+id/previewView" /> </FrameLayout>
Prośba o CameraProvider
Poniższy kod pokazuje, jak poprosić o 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) } }
Sprawdzanie dostępności CameraProvider
Po wysłaniu żądania CameraProvider sprawdź, czy inicjowanie się powiodło, gdy widok został utworzony. Poniższy kod pokazuje, jak to zrobić:
cameraProviderFuture.addListener( Runnable { val cameraProvider = cameraProviderFuture.get() bindPreview(cameraProvider) }, ContextCompat.getMainExecutor(this) )
Przykład funkcji bindPreview użytej w tym przykładzie znajdziesz w kodzie podanym w następnej sekcji.
Wybieranie kamery i powiązanie cyklu życia oraz przypadków użycia
Po utworzeniu i potwierdzeniu CameraProvider wykonaj te czynności:
- Utwórz
Preview. - Wybierz odpowiednią opcję kamery
LensFacing. - Powiąż wybrany aparat i wszystkie przypadki użycia z cyklem życia.
- Połącz
PreviewzPreviewView.
Oto przykładowy kod:
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) }
Pamiętaj, że bindToLifecycle() zwraca obiekt Camera. Więcej informacji o sterowaniu obrazem z kamery, np. powiększeniem i ekspozycją, znajdziesz w artykule Obraz z kamery.
Implementacja podglądu z aparatu została zakończona. Skompiluj aplikację i sprawdź, czy podgląd wyświetla się w niej i działa zgodnie z oczekiwaniami.
Dodatkowe ustawienia PreviewView
CameraX PreviewView udostępnia dodatkowe interfejsy API do konfigurowania właściwości takich jak:
- Tryb implementacji do renderowania strumieni podglądu.
- Typ skalowania obrazu podglądu.
Tryb wdrażania
PreviewView może używać jednego z tych trybów do renderowania strumienia podglądu na elemencie docelowym View:
PERFORMANCEto tryb domyślny.PreviewViewużywa elementuSurfaceViewdo wyświetlania strumienia wideo, ale w niektórych przypadkach korzysta z elementuTextureView.SurfaceViewma specjalną powierzchnię do rysowania, która ma większe szanse na wdrożenie z nakładką sprzętową przez wewnętrzny kompozytor sprzętowy, zwłaszcza gdy nad podglądem filmu nie ma innych elementów interfejsu (np. przycisków). Dzięki renderowaniu z nakładką sprzętową klatki wideo omijają ścieżkę GPU, co może zmniejszyć zużycie energii i opóźnienia platformy.COMPATIBLE. W tym trybiePreviewViewużywaTextureView, który w przeciwieństwie doSurfaceViewnie ma dedykowanej powierzchni do rysowania. W rezultacie film jest renderowany z mieszaniem, aby można go było wyświetlić. Podczas tego dodatkowego kroku aplikacja może wykonywać dodatkowe przetwarzanie, takie jak skalowanie i obracanie filmów bez ograniczeń.
Użyj PreviewView.setImplementationMode(), aby wybrać tryb implementacji odpowiedni dla Twojej aplikacji. Jeśli domyślny tryb PERFORMANCE nie jest odpowiedni dla Twojej aplikacji, ten przykładowy kod pokazuje, jak ustawić tryb COMPATIBLE:
// viewFinder is a PreviewView instance. viewFinder.implementationMode = PreviewView.ImplementationMode.COMPATIBLE
Typ skali
Gdy rozdzielczość filmu podglądu różni się od wymiarów celu PreviewView, treść wideo musi zostać dopasowana do widoku przez przycięcie lub dodanie czarnych pasów (zachowanie oryginalnego formatu obrazu). W tym celu PreviewView udostępnia te ScaleTypes:
FIT_CENTER,FIT_STARTiFIT_ENDw przypadku letterboxingu. Pełna treść wideo jest skalowana (w górę lub w dół) do maksymalnego możliwego rozmiaru, który można wyświetlić w docelowym elemenciePreviewView. Jednak mimo że cała klatka filmu jest widoczna, część ekranu może być pusta. W zależności od tego, który z tych 3 typów skali wybierzesz, klatka wideo zostanie wyrównana do środka, początku lub końca widoku docelowego.FILL_CENTER,FILL_START,FILL_ENDdo przycinania. Jeśli film nie ma formatu obrazuPreviewView, widoczna jest tylko część treści, ale film wypełnia cały obszarPreviewView.
Domyślny typ skali używany przez CameraX to FILL_CENTER. Użyj PreviewView.setScaleType(), aby ustawić typ skali najbardziej odpowiedni dla Twojej aplikacji. Poniższy przykładowy kod ustawia typ skali FIT_CENTER:
// viewFinder is a PreviewView instance. viewFinder.scaleType = PreviewView.ScaleType.FIT_CENTER
Proces wyświetlania filmu składa się z tych kroków:
- Skalowanie filmu:
- W przypadku typów skalowania
FIT_*przeskaluj film za pomocąmin(dst.width/src.width, dst.height/src.height). - W przypadku typów skalowania
FILL_*przeskaluj film za pomocąmax(dst.width/src.width, dst.height/src.height).
- W przypadku typów skalowania
- Wyrównaj przeskalowany film z miejscem docelowym
PreviewView:- W przypadku
FIT_CENTER/FILL_CENTERwyśrodkuj przeskalowany film i miejsce docelowePreviewView. - W przypadku
FIT_START/FILL_STARTwyrównaj przeskalowany film i miejsce docelowePreviewViewwzględem lewego górnego rogu każdego z nich. - W przypadku
FIT_END/FILL_ENDwyrównaj przeskalowany film i miejsce docelowePreviewViewwzględem prawego dolnego rogu każdego z nich.
- W przypadku
Na przykład tutaj mamy źródłowy film o wymiarach 640 x 480 i docelowy o wymiarach 1920 x 1080PreviewView:

Na ilustracji poniżej pokazano proces skalowania FIT_START / FIT_CENTER / FIT_END:

Proces przebiega w ten sposób:
- Przeskaluj klatkę filmu (zachowując oryginalny format obrazu) za pomocą
min(1920/640, 1080/480) = 2.25, aby uzyskać pośrednią klatkę filmu o wymiarach 1440 x 1080. - Wyrównaj klatkę filmu 1440 x 1080 z
PreviewView1920 x 1080.- W przypadku
FIT_CENTERwyrównaj klatkę filmu do środka oknaPreviewView. Początkowe i końcowe kolumny o szerokości 240 pikseli w elemenciePreviewViewsą puste. - W przypadku
FIT_STARTwyrównaj klatkę wideo z początkiem (lewym górnym rogiem) oknaPreviewView. Ostatnie 480 kolumn pikseli w plikuPreviewViewjest pustych. - W przypadku języka
FIT_ENDwyrównaj klatkę filmu z końcem (prawym dolnym rogiem) oknaPreviewView. Pierwsze 480 kolumn pikseli w plikuPreviewViewjest pustych.
- W przypadku
Na ilustracji poniżej pokazano proces skalowania FILL_START / FILL_CENTER / FILL_END:

Proces przebiega w ten sposób:
- Przeskaluj klatkę wideo za pomocą
max(1920/640, 1080/480) = 3, aby uzyskać pośrednią klatkę wideo o wymiarach 1920 x 1440 (która jest większa niż rozmiarPreviewView). - Przytnij klatkę filmu o wymiarach 1920 x 1440, aby dopasować ją do okna
PreviewViewo wymiarach 1920 x 1080.- W przypadku
FILL_CENTERprzytnij obraz do rozmiaru 1920 x 1080 ze środka przeskalowanego filmu o wymiarach 1920 x 1440. Górne i dolne 180 linii filmu nie jest widoczne. - W przypadku
FILL_STARTprzytnij 1920 x 1080 od początku przeskalowanego filmu 1920 x 1440. Dolne 360 linii filmu nie jest widoczne. - W przypadku
FILL_ENDprzytnij 1920 x 1080 od końca przeskalowanego filmu 1920 x 1440. Górne 360 linii filmu nie jest widoczne.
- W przypadku
Dodatkowe materiały
Więcej informacji o CameraX znajdziesz w tych materiałach.
Ćwiczenie w Codelabs
Przykładowy kod