Wdrażanie wersji przedpremierowej

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:

  1. Opcjonalnie skonfiguruj CameraXConfig.Provider.
  2. Dodaj PreviewView do układu.
  3. Poproś o ProcessCameraProvider.
  4. Podczas tworzenia View sprawdź, czy jest ProcessCameraProvider.
  5. 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ć TextureView i Preview.SurfaceProvider.
  • Pobierz SurfaceTexture z TextureView i ustaw w Preview.SurfaceProvider.
  • Pobierz Surface z SurfaceView i ustaw go na Preview.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:

  1. Utwórz Preview.
  2. Wybierz odpowiednią opcję kamery LensFacing.
  3. Powiąż wybrany aparat i wszystkie przypadki użycia z cyklem życia.
  4. Połącz Preview z PreviewView.

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 wdrażania

PreviewView może używać jednego z tych trybów do renderowania strumienia podglądu na elemencie docelowym View:

  • PERFORMANCE to tryb domyślny. PreviewView używa elementu SurfaceView do wyświetlania strumienia wideo, ale w niektórych przypadkach korzysta z elementu TextureView. SurfaceView ma 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 trybie PreviewView używa TextureView, który w przeciwieństwie do SurfaceView nie 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_START i FIT_END w 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 elemencie PreviewView. 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_END do przycinania. Jeśli film nie ma formatu obrazu PreviewView, widoczna jest tylko część treści, ale film wypełnia cały obszar PreviewView.

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:

  1. 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).
  2. Wyrównaj przeskalowany film z miejscem docelowym PreviewView:
    • W przypadku FIT_CENTER/FILL_CENTER wyśrodkuj przeskalowany film i miejsce docelowe PreviewView.
    • W przypadku FIT_START/FILL_START wyrównaj przeskalowany film i miejsce docelowe PreviewView względem lewego górnego rogu każdego z nich.
    • W przypadku FIT_END/FILL_END wyrównaj przeskalowany film i miejsce docelowe PreviewView względem prawego dolnego rogu każdego z nich.

Na przykład tutaj mamy źródłowy film o wymiarach 640 x 480 i docelowy o wymiarach 1920 x 1080PreviewView:

Obraz przedstawiający film w rozdzielczości 640 x 480 w porównaniu z podglądem w rozdzielczości 1920 x 1080

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

Obraz przedstawiający proces skalowania FIT_START, FIT_CENTER i FIT_END

Proces przebiega w ten sposób:

  1. 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.
  2. Wyrównaj klatkę filmu 1440 x 1080 z PreviewView 1920 x 1080.
    • W przypadku FIT_CENTER wyrównaj klatkę filmu do środka okna PreviewView. Początkowe i końcowe kolumny o szerokości 240 pikseli w elemencie PreviewView są puste.
    • W przypadku FIT_START wyrównaj klatkę wideo z początkiem (lewym górnym rogiem) okna PreviewView. Ostatnie 480 kolumn pikseli w pliku PreviewView jest pustych.
    • W przypadku języka FIT_END wyrównaj klatkę filmu z końcem (prawym dolnym rogiem) okna PreviewView. Pierwsze 480 kolumn pikseli w pliku PreviewView jest pustych.

Na ilustracji poniżej pokazano proces skalowania FILL_START / FILL_CENTER / FILL_END:

Obraz przedstawiający proces skalowania FILL_START, FILL_CENTER i FILL_END

Proces przebiega w ten sposób:

  1. 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ż rozmiar PreviewView).
  2. Przytnij klatkę filmu o wymiarach 1920 x 1440, aby dopasować ją do okna PreviewView o wymiarach 1920 x 1080.
    • W przypadku FILL_CENTER przytnij 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_START przytnij 1920 x 1080 od początku przeskalowanego filmu 1920 x 1440. Dolne 360 linii filmu nie jest widoczne.
    • W przypadku FILL_END przytnij 1920 x 1080 od końca przeskalowanego filmu 1920 x 1440. Górne 360 linii filmu nie jest widoczne.

Dodatkowe materiały

Więcej informacji o CameraX znajdziesz w tych materiałach.

Ćwiczenie w Codelabs

  • Pierwsze kroki z CameraX
  • Przykładowy kod

  • Przykładowe aplikacje CameraX