Vorschau implementieren

Wenn du deiner App eine Vorschau hinzufügst, verwende PreviewView. Dabei handelt es sich um ein View-Objekt, das für eine korrekte Darstellung zugeschnitten, skaliert und gedreht werden kann.

Die Bildvorschau wird an eine Oberfläche im PreviewView gestreamt, wenn die Kamera aktiv wird.

PreviewView verwenden

Das Implementieren 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 PreviewView hinzu.
  3. Fordern Sie ein ProcessCameraProvider an.
  4. Suchen Sie bei der View-Erstellung nach dem ProcessCameraProvider.
  5. Wählen Sie eine Kamera aus und verknüpfen Sie den Lebenszyklus und die Anwendungsfälle.

Die Verwendung von PreviewView unterliegt einigen Einschränkungen. Wenn Sie PreviewView verwenden, ist Folgendes nicht möglich:

  • Erstellen Sie eine SurfaceTexture, die für TextureView und Preview.SurfaceProvider festgelegt werden soll.
  • Rufen Sie die SurfaceTexture aus TextureView ab und legen Sie sie auf Preview.SurfaceProvider fest.
  • Rufen Sie die Surface von SurfaceView ab und legen Sie sie auf Preview.SurfaceProvider fest.

Wenn einer dieser Fälle eintritt, stoppt der Preview das Streaming von Frames zum PreviewView.

Dem Layout eine Vorschauansicht 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 ein CameraProvider angefordert wird:

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

Verfügbarkeit von CameraProvider prüfen

Nachdem Sie ein CameraProvider angefordert haben, prüfen Sie, ob die Initialisierung beim Erstellen der Ansicht erfolgreich war. Der folgende Code zeigt, wie das funktioniert:

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

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

Kamera auswählen und Lebenszyklus und Anwendungsfälle verknüpfen

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

  1. Erstellen Sie ein Preview.
  2. Geben Sie die gewünschte LensFacing-Kameraoption an.
  3. Binden Sie die ausgewählte Kamera und alle Anwendungsfälle an den Lebenszyklus.
  4. Verbinde Preview mit PreviewView.

Der folgende Code zeigt ein Beispiel:

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

bindToLifecycle() gibt ein Camera-Objekt zurück. Weitere Informationen zum Steuern der Kameraausgabe wie Zoom und Belichtung finden Sie unter Kameraausgabe.

Die Implementierung der Kameravorschau ist jetzt abgeschlossen. Erstellen Sie Ihre Anwendung und prüfen Sie, ob die Vorschau in der App angezeigt wird und wie vorgesehen funktioniert.

Zusätzliche Steuerelemente für PreviewView

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

Implementierungsmodus

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

  • PERFORMANCE ist der Standardmodus. PreviewView verwendet SurfaceView zum Anzeigen des Videostreams, verwendet jedoch in bestimmten Fällen ein TextureView. SurfaceView hat eine eigene Zeichenoberfläche, die mit größerer Wahrscheinlichkeit mit einem Hardware-Overlay vom internen Hardware-Compositor implementiert wird, insbesondere wenn sich über dem Vorschauvideo keine anderen UI-Elemente (z. B. Schaltflächen) befinden. Durch das Rendering mit einem Hardware-Overlay vermeiden Videoframes einen GPU-Pfad, wodurch der Stromverbrauch der Plattform und die Latenz reduziert werden können.

  • COMPATIBLE-Modus. In diesem Modus verwendet PreviewView ein TextureView, das im Gegensatz zu SurfaceView keine eigene Zeichenfläche hat. Das Video wird also mit Überblendung gerendert, damit es angezeigt werden kann. Während dieses zusätzlichen Schritts kann die Anwendung weitere Verarbeitungsschritte wie das Skalieren und Drehen von Videos ohne Einschränkung durchführen.

Verwenden Sie PreviewView.setImplementationMode(), um den für Ihre Anwendung geeigneten Implementierungsmodus auszuwählen. Wenn der standardmäßige PERFORMANCE-Modus für Ihre Anwendung nicht geeignet ist, zeigt das folgende Codebeispiel, wie der COMPATIBLE-Modus festgelegt wird:

Kotlin

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

Skalentyp

Wenn die Auflösung des Vorschauvideos von den Abmessungen des Ziel-PreviewView abweicht, muss der Videoinhalt durch Zuschneiden oder Letterbox-Bild (unter Beibehaltung des ursprünglichen Seitenverhältnisses) an die Ansicht angepasst werden. PreviewView stellt zu diesem Zweck Folgendes bereit: ScaleTypes:

  • FIT_CENTER, FIT_START und FIT_END für Letterbox-Bild. Der vollständige Videoinhalt wird auf die maximal mögliche Größe skaliert, die im Ziel-PreviewView angezeigt werden kann (entweder nach oben oder unten). Obwohl der vollständige Videoframe sichtbar ist, kann ein Teil des Bildschirms jedoch leer sein. Je nachdem, welchen dieser drei Skalentypen 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 die gesamte PreviewView aus.

Der Standard-Skalierungstyp von CameraX 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:

Kotlin

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

Um ein Video anzuzeigen, sind folgende Schritte erforderlich:

  1. Skalieren Sie das Video:
    • Bei Skalierungstypen vom Typ FIT_* wird das Video mit min(dst.width/src.width, dst.height/src.height) skaliert.
    • Bei Skalierungstypen vom Typ FILL_* wird das Video mit max(dst.width/src.width, dst.height/src.height) skaliert.
  2. Richten Sie das skalierte Video am Ziel-PreviewView aus:
    • Richten Sie bei FIT_CENTER/FILL_CENTER das skalierte Video und die Ziel-PreviewView zentriert aus.
    • Richten Sie bei FIT_START/FILL_START das skalierte Video und den Ziel-PreviewView jeweils in Bezug auf die obere linke Ecke aus.
    • Richten Sie bei FIT_END/FILL_END das skalierte Video und den Ziel-PreviewView jeweils in Bezug auf die untere rechte Ecke aus.

Hier sehen Sie beispielsweise ein Quellvideo der Größe 640 × 480 und ein Ziel-PreviewView von 1.920 × 1.080:

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

Die folgende Abbildung zeigt den Skalierungsprozess FIT_START / FIT_CENTER / FIT_END:

Bild, das den Skalierungsprozess FIT_START, FIT_CENTER und FIT_END zeigt

Der Vorgang läuft so ab:

  1. Skalieren Sie den Videoframe unter Beibehaltung des ursprünglichen Seitenverhältnisses mit min(1920/640, 1080/480) = 2.25, um einen Videoframe von 1440 × 1080 zu erhalten.
  2. Richten Sie den 1440 × 1080 großen Videoframe auf das 1920 × 1080 große PreviewView aus.
    • Richte bei FIT_CENTER den Videoframe an der Mitte des PreviewView-Fensters aus. Die Start- und Endspalten der 240-Pixel-Größe von PreviewView sind leer.
    • Richten Sie bei FIT_START den Videoframe am start (oben links) des PreviewView-Fensters aus. Die abschließenden Spalten von PreviewView mit 480 Pixeln sind leer.
    • Richten Sie bei FIT_END den Videoframe am Ende (unten rechts) des Fensters PreviewView aus. Die anfänglichen Spalten mit 480 Pixeln von PreviewView sind leer.

Die folgende Abbildung zeigt den Skalierungsprozess FILL_START / FILL_CENTER / FILL_END:

Abbildung mit dem Skalierungsprozess FILL_START, FILL_CENTER und FILL_END

Der Vorgang läuft so ab:

  1. Skalieren Sie den Videoframe mit max(1920/640, 1080/480) = 3, um einen Zwischenvideoframe von 1.920 × 1.440 zu erhalten, was größer als die Größe von PreviewView ist.
  2. Schneiden Sie den 1920 × 1440 großen Videoframe auf das 1920 × 1080 große PreviewView-Fenster zu.
    • Schneiden Sie bei FILL_CENTER das Bild auf 1920 × 1080 von der Mitte des 1920 × 1440 skalierten Videos zu. Die oberen und unteren 180 Videozeilen sind nicht sichtbar.
    • Schneiden Sie bei FILL_START am Anfang des 1920 × 1440 skalierten Videos auf 1.920 × 1.080 zu. Die unteren 360°-Videozeilen sind nicht sichtbar.
    • Schneiden Sie bei FILL_END das Ende des 1920 × 1440 skalierten Videos auf 1.920 × 1.080 zu. Die obersten 360 Zeilen des Videos sind nicht sichtbar.

Weitere Informationen

Weitere Informationen zu CameraX finden Sie in den folgenden zusätzlichen Ressourcen.

Codelab

  • Erste Schritte mit CameraX
  • Codebeispiel

  • CameraX-Beispiel-Apps