Podczas dodawania podglądu do aplikacji użyj PreviewView
– pliku View
, który można przyciąć, skalować i obrócić, aby zapewnić prawidłowe wyświetlanie.
Podgląd obrazu wyświetla się w elemencie wewnątrz elementu PreviewView
, gdy kamera staje się aktywna.
Korzystanie z podglądu
Wdrożenie podglądu dla AparatuX za pomocą PreviewView
obejmuje te kroki, które omówimy w późniejszych sekcjach:
- Opcjonalnie skonfiguruj
CameraXConfig.Provider
. - Dodaj
PreviewView
do układu. - Wyślij prośbę o
ProcessCameraProvider
. - Podczas tworzenia elementu
View
sprawdźProcessCameraProvider
. - Wybierz kamerę i powiąż cykl życia i przypadki użycia.
Korzystanie z usługi PreviewView
wiąże się z pewnymi ograniczeniami. Podczas korzystania z PreviewView
nie możesz:
- Utwórz
SurfaceTexture
i ustaw go dla elementówTextureView
iPreview.SurfaceProvider
. - Pobierz
SurfaceTexture
zTextureView
i ustaw go naPreview.SurfaceProvider
. - Pobierz
Surface
z usługiSurfaceView
i ustaw ją na urządzeniuPreview.SurfaceProvider
.
Jeśli wystąpi któraś z tych sytuacji, Preview
przestanie przesyłać klatki do PreviewView
.
Dodaj obiekt PreviewView do układu
Ten przykład pokazuje element PreviewView
w układzie:
<FrameLayout android:id="@+id/container"> <androidx.camera.view.PreviewView android:id="@+id/previewView" /> </FrameLayout>
Poproś o dostawcę CameraProvider
Ten kod pokazuje, jak poprosić o CameraProvider
:
Kotlin
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) } }
Java
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); } }
Sprawdź dostępność usługi CameraProvider
Po wysłaniu żądania CameraProvider
sprawdź, czy udało się go zainicjować podczas tworzenia widoku. Poniższy kod pokazuje, jak to zrobić:
Kotlin
cameraProviderFuture.addListener(Runnable { val cameraProvider = cameraProviderFuture.get() bindPreview(cameraProvider) }, ContextCompat.getMainExecutor(this))
Java
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));
Przykład użycia funkcji bindPreview
w tym przykładzie znajdziesz w następnej sekcji.
Wybierz kamerę i powiąż cykl życia i przypadki użycia
Po utworzeniu i potwierdzeniu CameraProvider
wykonaj te czynności:
- Utwórz
Preview
. - Określ żądaną opcję kamery
LensFacing
. - Powiąż wybraną kamerę i wszystkie przypadki użycia z cyklem życia.
- Połącz urządzenie
Preview
z:PreviewView
.
Oto przykład:
Kotlin
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) }
Java
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); }
Pamiętaj, że bindToLifecycle()
zwraca obiekt Camera
. Więcej informacji o sterowaniu działaniem aparatu (np. o powiększeniu i ekspozycji) znajdziesz w sekcji Wyjście kamery.
To już koniec wdrażania podglądu z aparatu. Utwórz aplikację i sprawdź, czy podgląd wyświetla się w aplikacji i działa zgodnie z oczekiwaniami.
Dodatkowe opcje widoku podglądu
CameraX PreviewView
udostępnia dodatkowe interfejsy API do konfigurowania właściwości, na przykład:
- Tryb implementacji służący do renderowania strumieni podglądu.
- Typ skalowania obrazu podglądu.
Tryb implementacji
PreviewView
może użyć jednego z tych trybów, aby renderować strumień podglądu w docelowym elemencie View
:
PERFORMANCE
to tryb domyślny.PreviewView
używa elementuSurfaceView
do wyświetlania strumienia wideo, ale w niektórych przypadkach zwraca wartośćTextureView
.SurfaceView
ma specjalną powierzchnię do rysowania, która daje większą szansę na implementację za pomocą nakładki sprzętowej za pomocą wewnętrznego kompozytora sprzętowego, zwłaszcza jeśli na podglądzie 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.COMPATIBLE
. W tym trybiePreviewView
używa elementuTextureView
, który w przeciwieństwie doSurfaceView
nie ma dedykowanej powierzchni do rysowania. W rezultacie film jest renderowany za pomocą mieszania, co umożliwia wyświetlenie. Ten dodatkowy krok umożliwia aplikacji wykonywanie dodatkowych operacji przetwarzania, takich jak skalowanie i obracanie filmów bez ograniczeń.
Aby wybrać tryb implementacji odpowiedni dla Twojej aplikacji, użyj funkcji PreviewView.setImplementationMode()
. Jeśli domyślny tryb PERFORMANCE
nie jest odpowiedni dla Twojej aplikacji, z tego przykładowego kodu dowiesz się, jak ustawić tryb COMPATIBLE
:
Kotlin
// viewFinder is a PreviewView instance viewFinder.implementationMode = PreviewView.ImplementationMode.COMPATIBLE
Typ skali
Jeśli rozdzielczość filmu z podglądem różni się od wymiarów elementu docelowego PreviewView
, treści wideo muszą zostać dopasowane do widoku przez przycięcie lub zastosowanie pasków do pasów (z zachowaniem pierwotnego formatu obrazu). W tym celu PreviewView
udostępnia te ScaleTypes
:
FIT_CENTER
,FIT_START
iFIT_END
na potrzeby obsługi letterbox. Pełne treści wideo są skalowane (w górę lub w dół) do maksymalnego możliwego rozmiaru, który można wyświetlić w docelowym elemenciePreviewView
. Mimo że pełna klatka wideo będzie widoczna, jej fragment może być pusty. W zależności od tego, który z tych 3 rodzajów skali wybierzesz, ramka wideo zostanie wyrównana do środka, początku lub końca docelowego widoku.FILL_CENTER
,FILL_START
,FILL_END
do przycinania. Jeśli film nie pasuje do formatuPreviewView
, widoczna będzie tylko część jego treści, ale wypełni on całyPreviewView
.
Domyślny typ skali używany przez Aparat X to FILL_CENTER
. Użyj PreviewView.setScaleType()
, aby ustawić typ skali najbardziej odpowiedni do Twojej aplikacji. Ten przykładowy kod ustawia typ skali FIT_CENTER
:
Kotlin
// viewFinder is a PreviewView instance viewFinder.scaleType = PreviewView.ScaleType.FIT_CENTER
Proces wyświetlania filmu składa się z następujących etapów:
- Dostosuj film do skali:
- W przypadku
FIT_*
typów skali skaluj film za pomocą metodymin(dst.width/src.width, dst.height/src.height)
. - W przypadku
FILL_*
typów skali skaluj film za pomocą metodymax(dst.width/src.width, dst.height/src.height)
.
- W przypadku
- Dopasuj przeskalowany film do miejsca docelowego
PreviewView
:- W przypadku elementu
FIT_CENTER/FILL_CENTER
wyśrodkuj skalowany film i miejsce docelowePreviewView
. - W przypadku
FIT_START/FILL_START
wyrównaj przeskalowany film i miejsce docelowePreviewView
względem lewego górnego rogu każdego z nich. - W przypadku
FIT_END/FILL_END
wyrównaj przeskalowany film i miejsce docelowePreviewView
względem prawego dolnego rogu każdego z nich.
- W przypadku elementu
Oto np. film źródłowy w rozdzielczości 640 × 480 i miejsce docelowe w rozdzielczości 1920 × 1080 PreviewView
:
Ten obraz przedstawia proces skalowania FIT_START
/ FIT_CENTER
/ FIT_END
:
Proces ten wygląda tak:
- Przeskaluj klatkę wideo (zachowując pierwotny współczynnik proporcji) za pomocą
min(1920/640, 1080/480) = 2.25
, aby uzyskać pośrednią klatkę wideo o wymiarach 1440 x 1080. - Dopasuj klatkę wideo o rozdzielczości 1440 x 1080 do
PreviewView
o rozdzielczości 1920 x 1080.- W przypadku
FIT_CENTER
wyrównaj klatkę wideo względem środka oknaPreviewView
. Początkowe i końcowe kolumny 240 pikseli obiektuPreviewView
są puste. - W przypadku
FIT_START
wyrównaj klatkę wideo z początkiem (lewym górnym rogiem) oknaPreviewView
. Końcowe kolumny 480 pikseli polaPreviewView
są puste. - W przypadku
FIT_END
wyrównaj klatkę wideo do końca (prawy dolny róg) oknaPreviewView
. Początkowe 480 pikseli kolumnyPreviewView
są puste.
- W przypadku
Ten obraz przedstawia proces skalowania FILL_START
/ FILL_CENTER
/ FILL_END
:
Proces ten wygląda tak:
- Przeskaluj klatkę wideo za pomocą funkcji
max(1920/640, 1080/480) = 3
, aby uzyskać pośrednią klatkę wideo o rozdzielczości 1920 x 1440 (która jest większa niż rozmiarPreviewView
). - Przytnij klatkę wideo o rozdzielczości 1920 x 1440, aby pasowała do okna
PreviewView
o wymiarach 1920 x 1080.- W przypadku
FILL_CENTER
przytnij rozmiar 1920 x 1080 od środka filmu przeskalowanego do rozdzielczości 1920 x 1440. Górne i dolne 180 wierszy filmu jest niewidocznych. - W przypadku
FILL_START
przytnij rozmiar 1920 x 1080 od początku filmu w skali 1920 x 1440. Dolne wiersze filmu 360° są niewidoczne. - W przypadku
FILL_END
przytnij rozmiar 1920 x 1080 od końca filmu w skali 1920 x 1440. Górne 360 wierszy filmu jest niewidoczne.
- W przypadku
Dodatkowe materiały
Więcej informacji o aplikacji CameraX znajdziesz w tych dodatkowych materiałach.
Ćwiczenia z programowania
Przykładowy kod