Wdrażanie wersji przedpremierowej

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:

  1. Opcjonalnie skonfiguruj CameraXConfig.Provider.
  2. Dodaj PreviewView do układu.
  3. Wyślij prośbę o ProcessCameraProvider.
  4. Podczas tworzenia elementu View sprawdź ProcessCameraProvider.
  5. 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ów TextureView i Preview.SurfaceProvider.
  • Pobierz SurfaceTexture z TextureView i ustaw go na Preview.SurfaceProvider.
  • Pobierz Surface z usługi SurfaceView i ustaw ją na urządzeniu Preview.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:

  1. Utwórz Preview.
  2. Określ żądaną opcję kamery LensFacing.
  3. Powiąż wybraną kamerę i wszystkie przypadki użycia z cyklem życia.
  4. 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

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 elementu SurfaceView 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 trybie PreviewView używa elementu TextureView, który w przeciwieństwie do SurfaceView 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 i FIT_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 elemencie PreviewView. 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 formatu PreviewView, widoczna będzie tylko część jego treści, ale wypełni on cały PreviewView.

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:

  1. Dostosuj film do skali:
    • W przypadku FIT_* typów skali skaluj film za pomocą metody min(dst.width/src.width, dst.height/src.height).
    • W przypadku FILL_* typów skali skaluj film za pomocą metody max(dst.width/src.width, dst.height/src.height).
  2. Dopasuj przeskalowany film do miejsca docelowego PreviewView:
    • W przypadku elementu FIT_CENTER/FILL_CENTER wyśrodkuj skalowany 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.

Oto np. film źródłowy w rozdzielczości 640 × 480 i miejsce docelowe w rozdzielczości 1920 × 1080 PreviewView:

Obraz przedstawiający film w rozdzielczości 640 x 480, a podgląd w rozdzielczości 1920 x 1080

Ten obraz przedstawia proces skalowania FIT_START / FIT_CENTER / FIT_END:

Obraz przedstawiający proces skalowania FIT_START, FIT_CENTER oraz FIT_END

Proces ten wygląda tak:

  1. 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.
  2. 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 okna PreviewView. Początkowe i końcowe kolumny 240 pikseli obiektu PreviewView są puste.
    • W przypadku FIT_START wyrównaj klatkę wideo z początkiem (lewym górnym rogiem) okna PreviewView. Końcowe kolumny 480 pikseli pola PreviewView są puste.
    • W przypadku FIT_END wyrównaj klatkę wideo do końca (prawy dolny róg) okna PreviewView. Początkowe 480 pikseli kolumny PreviewView są puste.

Ten obraz przedstawia proces skalowania FILL_START / FILL_CENTER / FILL_END:

Obraz przedstawiający proces skalowania FILL_START, FILL_CENTER i FILL_END

Proces ten wygląda tak:

  1. 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ż rozmiar PreviewView).
  2. 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.

Dodatkowe materiały

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

Ćwiczenia z programowania

  • Pierwsze kroki z Aparatem X
  • Przykładowy kod

  • Przykładowe aplikacje CameraX