Vorschau implementieren

Wenn du deiner App eine Vorschau hinzufügst, verwende PreviewView. Das ist ein View, der für eine korrekte Anzeige zugeschnitten, skaliert und gedreht werden kann.

Die Bildvorschau wird auf eine Oberfläche innerhalb des PreviewView gestreamt, wenn die Kamera aktiv wird.

PreviewView verwenden

Die Implementierung einer Vorschau für CameraX mit PreviewView umfasst die folgenden Schritte, die in späteren Abschnitten behandelt werden:

  1. Konfigurieren Sie optional einen CameraXConfig.Provider.
  2. Fügen Sie Ihrem Layout ein PreviewView hinzu.
  3. ProcessCameraProvider anfordern.
  4. Prüfen Sie bei der Erstellung von View, ob ProcessCameraProvider vorhanden ist.
  5. Wählen Sie eine Kamera aus und binden Sie den Lebenszyklus und die Anwendungsfälle.

Die Verwendung von PreviewView unterliegt einigen Einschränkungen. Wenn Sie PreviewView verwenden, können Sie Folgendes nicht tun:

  • Erstellen Sie eine SurfaceTexture, die Sie auf TextureView und Preview.SurfaceProvider festlegen können.
  • Rufen Sie die SurfaceTexture aus TextureView ab und legen Sie sie auf Preview.SurfaceProvider fest.
  • Rufen Sie den Surface aus SurfaceView ab und legen Sie ihn auf Preview.SurfaceProvider fest.

Wenn eines dieser Ereignisse eintritt, beendet der Preview das Streamen von Frames an den PreviewView.

PreviewView zum Layout hinzufügen

Das folgende Beispiel zeigt ein PreviewView in einem Layout:

<FrameLayout
    android:id="@+id/container">
        <androidx.camera.view.PreviewView
            android:id="@+id/previewView" />
</FrameLayout>

CameraProvider anfordern

Der folgende Code zeigt, wie Sie eine CameraProvider anfordern:

// 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)
    }
}

Verfügbarkeit von CameraProvider prüfen

Nachdem Sie einen CameraProvider angefordert haben, prüfen Sie, ob die Initialisierung erfolgreich war, wenn die Ansicht erstellt wird. Der folgende Code zeigt, wie das geht:

cameraProviderFuture.addListener(
    Runnable {
        val cameraProvider = cameraProviderFuture.get()
        bindPreview(cameraProvider)
    },
    ContextCompat.getMainExecutor(this)
)

Ein Beispiel für die in diesem Beispiel verwendete Funktion bindPreview finden Sie im Code im nächsten Abschnitt.

Kamera auswählen und Lebenszyklus und Anwendungsfälle binden

Nachdem Sie die CameraProvider erstellt und bestätigt haben, gehen Sie so vor:

  1. Erstellen Sie einen Preview.
  2. Gib die gewünschte Kameraoption LensFacing an.
  3. Binden Sie die ausgewählte Kamera und alle Anwendungsfälle an den Lebenszyklus.
  4. Verbinden Sie den Preview mit dem PreviewView.

Der folgende Code zeigt ein Beispiel:

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)
}

Beachten Sie, dass bindToLifecycle() ein Camera-Objekt zurückgibt. Weitere Informationen zum Steuern der Kameraausgabe, z. B. Zoom und Belichtung, finden Sie unter Kameraausgabe.

Sie haben die Kameravorschau jetzt implementiert. Erstellen Sie Ihre App und prüfen Sie, ob die Vorschau in Ihrer App angezeigt wird und wie gewünscht funktioniert.

Zusätzliche Steuerelemente für PreviewView

CameraX PreviewView bietet einige zusätzliche APIs zum Konfigurieren von Attributen wie:

Implementierungsmodus

PreviewView kann einen der folgenden Modi verwenden, um einen Vorschaustream auf dem Ziel-View zu rendern:

  • PERFORMANCE ist der Standardmodus. PreviewView verwendet ein SurfaceView, um den Videostream anzuzeigen, greift aber in bestimmten Fällen auf ein TextureView zurück. SurfaceView hat eine dedizierte Zeichenoberfläche, die mit höherer Wahrscheinlichkeit vom internen Hardware-Compositor mit einem Hardware-Overlay implementiert wird, insbesondere wenn sich keine anderen UI-Elemente (wie Schaltflächen) über dem Vorschauvideo befinden. Beim Rendern mit einem Hardware-Overlay wird der GPU-Pfad für Videoframes umgangen, was den Stromverbrauch und die Latenz der Plattform reduzieren kann.

  • COMPATIBLE-Modus. In diesem Modus verwendet PreviewView ein TextureView, das im Gegensatz zu SurfaceView keine dedizierte Zeichenfläche hat. Daher wird das Video mit Blending gerendert, damit es angezeigt werden kann. In diesem zusätzlichen Schritt kann die Anwendung weitere Verarbeitungsschritte ausführen, z. B. Videos ohne Einschränkung skalieren und drehen.

Wählen Sie mit PreviewView.setImplementationMode() den für Ihre Anwendung geeigneten Implementierungsmodus aus. Wenn der Standardmodus PERFORMANCE für Ihre Anwendung nicht geeignet ist, zeigt das folgende Codebeispiel, wie Sie den Modus COMPATIBLE festlegen:

// viewFinder is a PreviewView instance.
viewFinder.implementationMode = PreviewView.ImplementationMode.COMPATIBLE

Skalentyp

Wenn die Auflösung des Vorschauvideos von den Abmessungen des Ziels PreviewView abweicht, muss der Videoinhalt entweder durch Zuschneiden oder Letterboxing (Beibehalten des ursprünglichen Seitenverhältnisses) an die Ansicht angepasst werden. PreviewView bietet hierfür die folgenden ScaleTypes:

  • FIT_CENTER, FIT_START und FIT_END für Letterboxing. Der gesamte Videoinhalt wird auf die maximal mögliche Größe skaliert (entweder vergrößert oder verkleinert), die im Ziel-PreviewView angezeigt werden kann. Obwohl der gesamte Videoframe sichtbar ist, kann ein Teil des Bildschirms leer sein. Je nachdem, welchen dieser drei Skalierungstypen Sie auswählen, wird der Videoframe an der Mitte, am Anfang oder am Ende der Zielansicht ausgerichtet.

  • FILL_CENTER, FILL_START, FILL_END zum Zuschneiden. Wenn ein Video nicht dem Seitenverhältnis PreviewView entspricht, ist nur ein Teil des Inhalts sichtbar, aber das Video füllt das gesamte PreviewView aus.

Der von CameraX standardmäßig verwendete Skalierungstyp ist FILL_CENTER. Verwenden Sie PreviewView.setScaleType(), um den für Ihre Anwendung am besten geeigneten Skalierungstyp festzulegen. Im folgenden Codebeispiel wird der Skalierungstyp FIT_CENTER festgelegt:

// viewFinder is a PreviewView instance.
viewFinder.scaleType = PreviewView.ScaleType.FIT_CENTER

Die Wiedergabe eines Videos umfasst die folgenden Schritte:

  1. Video skalieren:
    • Skalieren Sie das Video für FIT_*-Skalierungstypen mit min(dst.width/src.width, dst.height/src.height).
    • Skalieren Sie das Video für FILL_*-Skalierungstypen mit max(dst.width/src.width, dst.height/src.height).
  2. Richten Sie das skalierte Video am Ziel PreviewView aus:
    • Richte bei FIT_CENTER/FILL_CENTER das skalierte Video und das Ziel PreviewView mittig aus.
    • Richten Sie für FIT_START/FILL_START das skalierte Video und das Ziel PreviewView an der oberen linken Ecke aus.
    • Richten Sie für FIT_END/FILL_END das skalierte Video und das Ziel PreviewView an der unteren rechten Ecke aus.

Hier ist beispielsweise ein Quellvideo mit 640 × 480 und ein Zielvideo mit 1920 × 1080PreviewView:

Bild, das ein Video mit 640 × 480 im Vergleich zu einer Vorschau mit 1920 × 1080 zeigt

Die folgende Abbildung zeigt den Skalierungsprozess für FIT_START / FIT_CENTER / FIT_END:

Abbildung des Skalierungsprozesses für FIT_START, FIT_CENTER und FIT_END

Der Vorgang läuft wie folgt ab:

  1. Skalieren Sie den Videoframe (unter Beibehaltung des ursprünglichen Seitenverhältnisses) mit min(1920/640, 1080/480) = 2.25, um einen Zwischenvideoframe von 1440 × 1080 zu erhalten.
  2. Richte den 1440x1080-Videoframe am 1920x1080-PreviewView aus.
    • Richten Sie für FIT_CENTER den Videoframe an der Mitte des PreviewView-Fensters aus. Die ersten und letzten 240 Pixelspalten des PreviewView sind leer.
    • Richten Sie für FIT_START den Videoframe am Anfang (obere linke Ecke) des PreviewView-Fensters aus. Die letzten 480 Pixelspalten des PreviewView sind leer.
    • Richten Sie für FIT_END den Videoframe am Ende (rechte untere Ecke) des PreviewView-Fensters aus. Die ersten 480 Pixelspalten des PreviewView sind leer.

Die folgende Abbildung zeigt den Skalierungsprozess für FILL_START / FILL_CENTER / FILL_END:

Bild, das den Skalierungsprozess für FILL_START, FILL_CENTER und FILL_END zeigt

Der Vorgang läuft wie folgt ab:

  1. Skalieren Sie den Videoframe mit max(1920/640, 1080/480) = 3, um einen Zwischenvideoframe von 1920 × 1440 zu erhalten (der größer als die Größe von PreviewView ist).
  2. Schneiden Sie den Videoframe mit 1920 × 1440 Pixeln so zu, dass er in das PreviewView-Fenster mit 1920 × 1080 Pixeln passt.
    • Schneiden Sie für FILL_CENTER 1920 × 1080 aus der Mitte des skalierten Videos mit 1920 × 1440 aus. Die oberen und unteren 180 Zeilen des Videos sind nicht sichtbar.
    • Schneide für FILL_START 1920 × 1080 vom Anfang des skalierten Videos mit 1920 × 1440 aus. Die unteren 360 Zeilen des Videos sind nicht sichtbar.
    • Schneide für FILL_END 1920 × 1080 vom Ende des skalierten Videos mit 1920 × 1440 aus. Die oberen 360 Zeilen des Videos sind nicht sichtbar.

Zusätzliche Ressourcen

Weitere Informationen zu CameraX finden Sie in den folgenden Ressourcen.

Codelab

  • Erste Schritte mit CameraX
  • Codebeispiel

  • CameraX-Beispiel-Apps