Quando aggiungi un'anteprima alla tua app, usa PreviewView
, ovvero una View
che può essere ritagliata, ridimensionata e ruotata per una visualizzazione corretta.
Quando la videocamera diventa attiva, l'anteprima dell'immagine viene riprodotta in streaming su una superficie all'interno di PreviewView
.
Utilizzare la visualizzazione Anteprima
L'implementazione di un'anteprima per CameraX utilizzando PreviewView
prevede i seguenti passaggi, illustrati nelle sezioni successive:
- Facoltativamente, configura una
CameraXConfig.Provider
. - Aggiungi un elemento
PreviewView
al layout. - Richiedi una
ProcessCameraProvider
. - Al momento della creazione di
View
, controlla se è presenteProcessCameraProvider
. - Seleziona una videocamera e associa il ciclo di vita e i casi d'uso.
L'utilizzo di PreviewView
presenta alcune limitazioni. Quando utilizzi PreviewView
, non puoi eseguire nessuna delle seguenti operazioni:
- Crea un
SurfaceTexture
da impostare suTextureView
ePreview.SurfaceProvider
. - Recupera
SurfaceTexture
daTextureView
e impostalo suPreview.SurfaceProvider
. - Scarica
Surface
daSurfaceView
e impostala suPreview.SurfaceProvider
.
Se si verifica una di queste condizioni, Preview
interrompe lo streaming dei frame in PreviewView
.
Aggiungere un elemento PreviewView al layout
Il seguente esempio mostra un elemento PreviewView
in un layout:
<FrameLayout android:id="@+id/container"> <androidx.camera.view.PreviewView android:id="@+id/previewView" /> </FrameLayout>
Richiedi un CameraProvider
Il codice seguente 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); } }
Verifica la disponibilità di CameraProvider
Dopo aver richiesto un CameraProvider
, verifica che l'inizializzazione sia riuscita al momento della creazione della vista. Il seguente codice mostra come eseguire questa operazione:
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 fornito nella prossima sezione.
Selezionare una videocamera e associare il ciclo di vita e i casi d'uso
Dopo aver creato e confermato il CameraProvider
, procedi nel seguente modo:
- Crea un
Preview
. - Specifica l'opzione
LensFacing
per la videocamera che ti interessa. - Associa la videocamera selezionata e i casi d'uso al ciclo di vita.
- Collega
Preview
aPreviewView
.
Il codice seguente 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 oggetto Camera
. Per ulteriori informazioni su come controllare l'output della videocamera, come lo zoom e l'esposizione, vedi Output videocamera.
A questo punto, hai completato l'implementazione dell'anteprima della fotocamera. Crea la tua app e verifica che l'anteprima venga visualizzata e funzioni come previsto.
Controlli aggiuntivi per PreviewView
CameraX PreviewView
fornisce alcune API aggiuntive per configurare proprietà come:
- La modalità di implementazione per il rendering degli stream di anteprima.
- Il tipo di scala dell'immagine di anteprima.
Modalità di implementazione
PreviewView
può utilizzare una delle seguenti modalità per eseguire il rendering di uno stream di anteprima sulla destinazione View
:
PERFORMANCE
è la modalità predefinita.PreviewView
utilizza un elementoSurfaceView
per visualizzare lo stream video, ma in determinati casi utilizza un valoreTextureView
.SurfaceView
ha una superficie di disegno dedicata, che ha maggiori probabilità di essere implementato con un overlay hardware da parte del compositore hardware interno, soprattutto quando non ci sono altri elementi dell'interfaccia utente (come i pulsanti) nella parte superiore del video di anteprima. Grazie al rendering con una sovrapposizione hardware, i frame video evitano il percorso della GPU, il che può ridurre il consumo di energia e la latenza della piattaforma.COMPATIBLE
. In questa modalità,PreviewView
utilizza un elementoTextureView
che, a differenza diSurfaceView
, non ha una superficie di disegno dedicata. Di conseguenza, il video viene visualizzato con una combinazione di elementi in modo da poter essere visualizzato. Durante questo passaggio aggiuntivo, l'applicazione può eseguire altre elaborazioni, ad esempio scalare e ruotare i video senza limitazioni.
Utilizza PreviewView.setImplementationMode()
per selezionare la modalità di implementazione adatta alla tua applicazione. Se la modalità PERFORMANCE
predefinita non è adatta alla tua applicazione, il seguente codice di esempio mostra come impostare la modalità COMPATIBLE
:
Kotlin
// viewFinder is a PreviewView instance viewFinder.implementationMode = PreviewView.ImplementationMode.COMPATIBLE
Tipo di scala
Quando la risoluzione del video di anteprima è diversa dalle dimensioni dell'elemento PreviewView
target, i contenuti video devono essere adattati alla visualizzazione ritagliando o modificando le proporzioni (mantenendo le proporzioni originali). PreviewView
fornisce il seguente ScaleTypes
a questo scopo:
FIT_CENTER
,FIT_START
eFIT_END
per il letterbox. L'intero contenuto video viene ridimensionato (in alto o in basso) alla massima dimensione possibile visualizzabile nell'PreviewView
di destinazione. Tuttavia, sebbene sia visibile l'intero frame del video, alcune parti dello schermo potrebbero essere vuote. A seconda di quali di questi tre tipi di scala scegli, il frame video verrà allineato al centro, all'inizio o alla fine della vista di destinazione.FILL_CENTER
,FILL_START
,FILL_END
per il ritaglio. Se un video non corrisponde alle proporzioniPreviewView
, è visibile solo una parte dei contenuti, ma il video riempie l'interoPreviewView
.
Il tipo di scala predefinito utilizzato da CameraX è FILL_CENTER
. Utilizza PreviewView.setScaleType()
per impostare il tipo di scala più appropriato per la tua applicazione. Il seguente esempio di codice 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:
- Ridimensiona il video:
- Per i tipi di scala
FIT_*
, scala il video conmin(dst.width/src.width, dst.height/src.height)
. - Per i tipi di scala
FILL_*
, scala il video conmax(dst.width/src.width, dst.height/src.height)
.
- Per i tipi di scala
- Allinea il video in scala alla
PreviewView
di destinazione:- Per
FIT_CENTER/FILL_CENTER
, allinea al centro il video in scala e la destinazionePreviewView
. - Per
FIT_START/FILL_START
, allinea il video in scala e la destinazionePreviewView
rispetto all'angolo in alto a sinistra di ciascuno. - Per
FIT_END/FILL_END
, allinea il video in scala e la destinazionePreviewView
rispetto all'angolo in basso a destra di ciascuno.
- Per
Ad esempio, ecco un video di origine in formato 640 x 480 e una destinazione in formato 1920 x 1080
PreviewView
:
L'immagine seguente mostra il processo di scalabilità
FIT_START
/ FIT_CENTER
/ FIT_END
:
La procedura funziona nel seguente modo:
- 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. - Allinea il frame video 1440 x 1080 con l'
PreviewView
1920 x 1080.- Per
FIT_CENTER
, allinea il frame del video al centro della finestraPreviewView
. Le colonne iniziali e finali di 240 pixel della colonnaPreviewView
sono vuote. - Per
FIT_START
, allinea il frame del video all'inizio (angolo in alto a sinistra) della finestraPreviewView
. Le colonne finali da 480 pixel dellaPreviewView
sono vuote. - Per
FIT_END
, allinea il frame del video alla fine (angolo in basso a destra) della finestra diPreviewView
. Le colonne iniziali da 480 pixel diPreviewView
sono vuote.
- Per
L'immagine seguente mostra il processo di scalabilità
FILL_START
/ FILL_CENTER
/ FILL_END
:
La procedura funziona nel seguente modo:
- Ridimensiona il frame video con
max(1920/640, 1080/480) = 3
per ottenere un frame video intermedio di 1920 x 1440, ovvero maggiore delle dimensioni diPreviewView
. - Ritaglia il frame video 1920x1440 per adattarlo alla finestra 1920x1080
PreviewView
.- Per
FILL_CENTER
, ritaglia la dimensione 1920 x 1080 dal centro del video in scala 1920 x 1440. Le 180 righe superiore e inferiore del video non sono visibili. - Per
FILL_START
, ritaglia la dimensione 1920 x 1080 dall'inizio del video in scala 1920 x 1440. Le ultime 360 righe del video non sono visibili. - Per
FILL_END
, ritaglia la dimensione 1920 x 1080 dalla fine del video in scala 1920 x 1440. Le prime 360 righe del video non sono visibili.
- Per
Risorse aggiuntive
Per scoprire di più su CameraX, consulta le seguenti risorse aggiuntive.
Codelab
Esempio di codice