Implementare un'anteprima

Quando aggiungi un'anteprima alla tua app, usa PreviewView, che è un View che possono essere ritagliati, ridimensionati e ruotati per una corretta visualizzazione.

L'anteprima dell'immagine viene trasmessa in streaming a una piattaforma all'interno di PreviewView quando la videocamera diventa attiva.

Utilizzare la Visualizzazione anteprima

L'implementazione di un'anteprima per CameraX utilizzando PreviewView prevede quanto segue passaggi, che verranno trattati nelle sezioni successive:

  1. Facoltativamente, configura un CameraXConfig.Provider
  2. Aggiungi un PreviewView al layout.
  3. Richiedi un ProcessCameraProvider
  4. Al momento della creazione di View, controlla il ProcessCameraProvider.
  5. Seleziona una videocamera e associa il ciclo di vita e i casi d'uso.

L'uso di PreviewView presenta alcune limitazioni. Quando utilizzi PreviewView, non puoi eseguire una delle seguenti operazioni:

  • Crea un SurfaceTexture da impostare su TextureView e Preview.SurfaceProvider
  • Recupera SurfaceTexture da TextureView e impostalo su Preview.SurfaceProvider.
  • Prendi il Surface da SurfaceView e impostalo su Preview.SurfaceProvider.

Se si verifica una di queste situazioni, Preview interrompe lo streaming dei frame al PreviewView.

Aggiungere una visualizzazione di anteprima al layout

L'esempio seguente mostra un PreviewView in un layout:

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

Richiedi un CameraProvider

Il seguente codice mostra come richiedere un 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);
    }
}

Verificare la disponibilità di CameraProvider

Dopo aver richiesto un CameraProvider, verifica che l'inizializzazione sia riuscita quando viene creata la vista. Il seguente codice mostra come fare:

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

Per un esempio della funzione bindPreview utilizzata in questo esempio, consulta il codice fornita nella sezione successiva.

Seleziona una videocamera e associa il ciclo di vita e i casi d'uso

Dopo aver creato e confermato CameraProvider, procedi nel seguente modo:

  1. Crea un Preview.
  2. Specifica l'opzione LensFacing della fotocamera che preferisci.
  3. Associa la videocamera selezionata e gli eventuali casi d'uso al ciclo di vita.
  4. Collega Preview a PreviewView.

Il seguente codice mostra un esempio:

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

Tieni presente che bindToLifecycle() restituisce un Camera . Per ulteriori informazioni sul controllo dell'output della fotocamera, ad esempio lo zoom e di esposizione, vedi Output fotocamera.

Hai completato l'implementazione dell'anteprima della fotocamera. Crea la tua app e conferma che l'anteprima venga visualizzata nell'app e funzioni come previsto.

Controlli aggiuntivi per PreviewView

CameraX PreviewView fornisce alcune API aggiuntive per configurare proprietà quali come:

Modalità di implementazione

PreviewView può utilizzare una delle seguenti modalità per eseguire il rendering di uno stream di anteprima su View target:

  • PERFORMANCE è la modalità predefinita. PreviewView utilizza un SurfaceView per visualizzare il video ma utilizza un valore TextureView in determinati casi. SurfaceView ha una superficie di disegno dedicata, che ha maggiori probabilità di essere implementato con un overlay hardware dal compositore hardware interno, soprattutto quando non sono presenti altri elementi UI (come pulsanti) sopra il video di anteprima. Eseguendo il rendering con un hardware overlay, i frame video evitano un percorso GPU, il che può ridurre la potenza della piattaforma consumo e latenza.

  • COMPATIBLE . In questa modalità, PreviewView utilizza un TextureView che, a differenza di SurfaceView non dispone di una superficie di disegno dedicata. Di conseguenza, i video esegue il rendering con la combinazione in modo da poter essere visualizzati. Durante questo passaggio aggiuntivo, applicazione può eseguire ulteriori elaborazioni, come la scalabilità e video senza restrizioni.

Utilizza PreviewView.setImplementationMode() per selezionare la modalità di implementazione adatta alla tua applicazione. Se l'impostazione predefinita La modalità PERFORMANCE non è adatta alla tua applicazione, il codice seguente esempio mostra come impostare la modalità COMPATIBLE:

Kotlin

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

Tipo di bilancia

Quando la risoluzione del video di anteprima è diversa dalle dimensioni del target PreviewView, i contenuti del video devono essere adattati alla visualizzazione tramite ritaglio o letterbox (mantenendo le proporzioni originali). PreviewView fornisce il parametro persone che segui ScaleTypes a questo scopo:

  • FIT_CENTER, FIT_START, e FIT_END per il letterbox. L'intero contenuto del video viene ridimensionato (verso l'alto o verso il basso) dimensione massima possibile che può essere visualizzata nel PreviewView target. Tuttavia, sebbene sia visibile l'intero fotogramma video, parte dello schermo potrebbero essere vuoti. In base a quali di questi tre tipi di scala scegli, il fotogramma video si allinea al centro, all'inizio o alla fine della vista target.

  • FILL_CENTER, FILL_START, FILL_END per ritagliato. Se un video non corrisponde alle proporzioni PreviewView, viene restituito solo un parte dei contenuti è visibile, ma il video riempie l'intero PreviewView.

Il tipo di bilancia predefinito utilizzato da CameraX è FILL_CENTER. Utilizza PreviewView.setScaleType() per impostare il tipo di scala più appropriato per la tua applicazione. Il seguente codice esempio imposta il tipo di scala FIT_CENTER:

Kotlin

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

La procedura per la visualizzazione di un video prevede i seguenti passaggi:

  1. Ridimensiona il video:
    • Per i tipi di scala FIT_*, scala il video con min(dst.width/src.width, dst.height/src.height).
    • Per i tipi di scala FILL_*, scala il video con max(dst.width/src.width, dst.height/src.height).
  2. Allinea il video in scala con la destinazione PreviewView:
    • Per FIT_CENTER/FILL_CENTER, allinea al centro il video in scala e la destinazione PreviewView.
    • Per FIT_START/FILL_START, allinea il video in scala e la destinazione PreviewView rispetto all'angolo in alto a sinistra di ognuna.
    • Per FIT_END/FILL_END, allinea il video in scala e la destinazione PreviewView rispetto all'angolo in basso a destra di ognuna.

Ad esempio, ecco un video di origine 640 x 480 e una destinazione 1920 x 1080 PreviewView:

Immagine che mostra un video di 640 x 480 rispetto all&#39;anteprima di 1920 x 1080

La seguente immagine mostra FIT_START / FIT_CENTER / FIT_END di grandi dimensioni:

Immagine che mostra il processo di scalabilità FIT_START, FIT_CENTER e FIT_END

La procedura funziona nel seguente modo:

  1. Ridimensiona il frame video (mantenendo le proporzioni originali) con min(1920/640, 1080/480) = 2.25 per ottenere un fotogramma video intermedio di 1440 x 1080.
  2. Allinea la cornice video 1440 x 1080 con la PreviewView di 1920 x 1080.
    • Per FIT_CENTER, allinea il fotogramma video al centro dello PreviewView finestra. Le colonne di 240 pixel iniziali e finali del PreviewView è vuoto.
    • Per FIT_START, allinea il fotogramma video con inizio (nell'angolo in alto a sinistra) della finestra PreviewView. Le colonne finali da 480 pixel dell'PreviewView sono vuote.
    • Per FIT_END, allinea il fotogramma del video alla fine (nell'angolo in basso a destra) della finestra PreviewView. Le colonne iniziali da 480 pixel PreviewView è vuoto.

La seguente immagine mostra FILL_START / FILL_CENTER / FILL_END di grandi dimensioni:

Immagine che mostra il processo di scalabilità di FILL_START, FILL_CENTER e FILL_END

La procedura funziona nel seguente modo:

  1. Scala il frame video con max(1920/640, 1080/480) = 3 per ottenere un frame video intermedio di 1920 x 1440 (che supera le dimensioni del PreviewView).
  2. Ritaglia la cornice video 1920 x 1440 per adattarla alla finestra di PreviewView di 1920 x 1080.
    • Per FILL_CENTER, ritaglia la dimensione 1920 x 1080 dal centro dell'immagine 1920 x 1440 video scalato. Le 180 righe superiori e inferiori del video non sono visibili.
    • Per FILL_START, ritaglia la dimensione 1920 x 1080 dall'inizio del formato 1920 x 1440 in scala video. Le ultime 360 righe del video non sono visibili.
    • Per FILL_END, ritaglia la dimensione 1920 x 1080 dalla fine del formato 1920 x 1440 in scala video. Le prime 360 righe del video non sono visibili.

Risorse aggiuntive

Per saperne di più su CameraX, consulta le risorse aggiuntive che seguono.

Codelab

  • Iniziare a usare CameraX
  • Esempio di codice

  • Esempi di app CameraX