Puoi configurare ogni caso d'uso di CameraX per controllare aspetti diversi dell'utilizzo le operazioni del caso.
Ad esempio, con il caso d'uso di acquisizione di immagini, puoi impostare proporzioni target e una modalità flash. Il codice che segue mostra un esempio:
Kotlin
val imageCapture = ImageCapture.Builder() .setFlashMode(...) .setTargetAspectRatio(...) .build()
Java
ImageCapture imageCapture = new ImageCapture.Builder() .setFlashMode(...) .setTargetAspectRatio(...) .build();
Oltre alle opzioni di configurazione, alcuni casi d'uso espongono le API ai e modificare le impostazioni dopo aver creato il caso d'uso. Per informazioni su specifica per i singoli casi d'uso, consulta Implementare un anteprima, Analizza immagini e Immagine acquisizioni.
Configurazione CameraX
Per semplicità, CameraX dispone di configurazioni predefinite come esecutori interni
e gestori adatti alla maggior parte degli scenari di utilizzo. Tuttavia, se
l'applicazione ha requisiti speciali o preferisce personalizzarli
configurazioni, CameraXConfig
è l'interfaccia.
Con CameraXConfig
, un'applicazione può:
- Ottimizza la latenza di avvio con
setAvailableCameraLimiter()
- Fornisci l'esecutore dell'applicazione a CameraX con
setCameraExecutor()
- Sostituisci il gestore dello scheduler predefinito con
setSchedulerHandler()
- Modifica il livello di logging con
setMinimumLoggingLevel()
Modello di utilizzo
La seguente procedura descrive come utilizzare CameraXConfig
:
- Crea un oggetto
CameraXConfig
con le tue configurazioni personalizzate. - Implementa il
CameraXConfig.Provider
nell'interfaccia diApplication
restituiscono l'oggettoCameraXConfig
getCameraXConfig()
- Aggiungi il corso
Application
al fileAndroidManifest.xml
come descritti qui.
Ad esempio, il seguente esempio di codice limita il logging di CameraX all'errore solo messaggi:
Kotlin
class CameraApplication : Application(), CameraXConfig.Provider { override fun getCameraXConfig(): CameraXConfig { return CameraXConfig.Builder.fromConfig(Camera2Config.defaultConfig()) .setMinimumLoggingLevel(Log.ERROR).build() } }
Conserva una copia locale dell'oggetto CameraXConfig
se l'applicazione richiede
conoscere la configurazione di CameraX
dopo averla impostata.
Limitatore fotocamera
Durante la prima chiamata a
ProcessCameraProvider.getInstance()
,
CameraX elenca e interroga le caratteristiche delle fotocamere disponibili sul
dispositivo. Dal momento che CameraX deve comunicare con i componenti hardware, questo
di questo processo può richiedere un tempo non banale per ogni videocamera, in particolare
dispositivi di fascia bassa. Se l'applicazione utilizza solo fotocamere specifiche sul dispositivo,
come la fotocamera anteriore predefinita, puoi impostare CameraX in modo che ignori le altre fotocamere,
il che può ridurre la latenza di avvio per le videocamere utilizzate dalla tua applicazione.
Se CameraSelector
ha superato l'esame
a
CameraXConfig.Builder.setAvailableCamerasLimiter()
esclude una videocamera, CameraX si comporta come se quella videocamera non esistesse. Per
Ad esempio, il codice che segue limita l'applicazione all'uso esclusivo del
fotocamera posteriore predefinita:
Kotlin
class MainApplication : Application(), CameraXConfig.Provider { override fun getCameraXConfig(): CameraXConfig { return CameraXConfig.Builder.fromConfig(Camera2Config.defaultConfig()) .setAvailableCamerasLimiter(CameraSelector.DEFAULT_BACK_CAMERA) .build() } }
Thread
Molte delle API delle piattaforme su cui è basata CameraX richiedono il blocco
le comunicazioni tra i processi (IPC) e hardware; a volte possono richiedere centinaia
di millisecondi per rispondere. Per questo motivo, CameraX chiama queste API solo da
thread in background, in modo che il thread principale non venga bloccato e la UI
rimane fluido. CameraX gestisce internamente questi thread in background in modo che
il comportamento degli utenti appare trasparente. Tuttavia, alcune applicazioni richiedono un controllo rigoroso
di thread. CameraXConfig
consente a un'applicazione di impostare i thread in background
utilizzate tramite
CameraXConfig.Builder.setCameraExecutor()
e
CameraXConfig.Builder.setSchedulerHandler()
.
Esecutore videocamera
L'esecutore fotocamera viene utilizzato anche per tutte le chiamate API della piattaforma Camera interna
per i callback da queste API. CameraX alloca e gestisce un server
Executor
per eseguire queste attività.
Tuttavia, se la tua applicazione richiede un controllo più rigoroso dei thread, usa
CameraXConfig.Builder.setCameraExecutor()
.
Gestore scheduler
Il gestore dello scheduler viene utilizzato per pianificare le attività interne a intervalli fissi,
come ad esempio riprovare ad aprire la fotocamera quando non è disponibile. Questo gestore
non esegue i job, ma li invia soltanto all'esecutore della videocamera. È inoltre possibile
talvolta utilizzate sulle piattaforme API legacy che richiedono una
Handler
per i callback. In questi casi,
i callback vengono comunque inviati direttamente all'esecutore della videocamera. FotocameraX
alloca e gestisce una query
HandlerThread
per eseguire queste attività,
ma puoi eseguirne l'override con CameraXConfig.Builder.setSchedulerHandler()
.
Logging
Il logging di CameraX consente alle applicazioni di filtrare i messaggi Logcat, poiché può essere utile per evitare messaggi dettagliati nel codice di produzione. FotocameraX supporta quattro livelli di registrazione, dal più dettagliato al più grave:
Log.DEBUG
(valore predefinito)Log.INFO
Log.WARN
Log.ERROR
Consulta la documentazione relativa ai log Android
per una descrizione dettagliata di questi livelli di log. Utilizza le funzionalità di
CameraXConfig.Builder.setMinimumLoggingLevel(int)
per impostare il livello di logging appropriato per la tua applicazione.
Selezione automatica
CameraX fornisce automaticamente funzionalità specifiche per il dispositivo che su cui è in esecuzione la tua app. Ad esempio, CameraX determina automaticamente risoluzione migliore da utilizzare se non ne specifichi una o se specificato non è supportato. Tutto questo viene gestito dalla libreria, eliminando non è necessario scrivere codice specifico per il dispositivo.
L'obiettivo di CameraX è inizializzare correttamente una sessione della videocamera. Ciò significa CameraX compromette risoluzione e proporzioni in base alle funzionalità del dispositivo. La compromissione può verificarsi perché:
- Il dispositivo non supporta la risoluzione richiesta.
- Il dispositivo presenta problemi di compatibilità, ad esempio dispositivi legacy che richiedono alcune risoluzioni per funzionare correttamente.
- Su alcuni dispositivi, alcuni formati sono disponibili soltanto in determinati aspetti proporzioni.
- Il dispositivo ha una preferenza per un "mod16 più vicino" per JPEG o video
codifica. Per ulteriori informazioni, vedi
SCALER_STREAM_CONFIGURATION_MAP
Anche se CameraX crea e gestisce la sessione, controlla sempre le dimensioni delle immagini restituite nell'output del caso d'uso nel codice e regolarle di conseguenza.
Rotazione
Per impostazione predefinita, la rotazione della videocamera è impostata in modo che corrisponda a quella del display predefinito durante la creazione del caso d'uso. In questo caso predefinito, CameraX produce per consentire all'app di corrispondere a ciò che ti aspetti l'anteprima. Puoi modificare la rotazione impostandola su un valore personalizzato per supportare la visualizzazione multi-display dispositivi passando l'orientamento del display corrente durante la configurazione del caso d'uso o in modo dinamico dopo la loro creazione.
La tua app può impostare la rotazione target utilizzando le impostazioni di configurazione. Può quindi
aggiornare le impostazioni di rotazione utilizzando i metodi delle API dei casi d'uso (come
ImageAnalysis.setTargetRotation()
),
anche mentre il ciclo di vita è in esecuzione. Potresti usarla quando l'app
è bloccato alla modalità verticale, pertanto non avviene alcuna riconfigurazione
rotazione, ma il caso d'uso della foto o dell'analisi deve conoscere il
la rotazione corrente del dispositivo. Ad esempio, potrebbe essere necessario il rilevamento della rotazione
quindi
i volti sono orientati correttamente per il rilevamento facciale oppure le foto sono impostate sulla modalità Orizzontale
o con orientamento verticale.
I dati delle immagini acquisite potrebbero essere archiviati senza informazioni sulla rotazione. Dati EXIF contiene informazioni sulla rotazione per consentire alle applicazioni galleria di visualizzare l'immagine in l'orientamento corretto dopo il salvataggio.
Per visualizzare i dati di anteprima con l'orientamento corretto, puoi utilizzare i metadati
output da
Preview.PreviewOutput()
per creare trasformazioni.
Il seguente esempio di codice mostra come impostare la rotazione su un evento di orientamento:
Kotlin
override fun onCreate() { val imageCapture = ImageCapture.Builder().build() val orientationEventListener = object : OrientationEventListener(this as Context) { override fun onOrientationChanged(orientation : Int) { // Monitors orientation values to determine the target rotation value val rotation : Int = when (orientation) { in 45..134 -> Surface.ROTATION_270 in 135..224 -> Surface.ROTATION_180 in 225..314 -> Surface.ROTATION_90 else -> Surface.ROTATION_0 } imageCapture.targetRotation = rotation } } orientationEventListener.enable() }
Java
@Override public void onCreate() { ImageCapture imageCapture = new ImageCapture.Builder().build(); OrientationEventListener orientationEventListener = new OrientationEventListener((Context)this) { @Override public void onOrientationChanged(int orientation) { int rotation; // Monitors orientation values to determine the target rotation value if (orientation >= 45 && orientation < 135) { rotation = Surface.ROTATION_270; } else if (orientation >= 135 && orientation < 225) { rotation = Surface.ROTATION_180; } else if (orientation >= 225 && orientation < 315) { rotation = Surface.ROTATION_90; } else { rotation = Surface.ROTATION_0; } imageCapture.setTargetRotation(rotation); } }; orientationEventListener.enable(); }
In base alla rotazione impostata, ogni caso d'uso ruota i dati dell'immagine o fornisce metadati di rotazione ai consumatori dell'immagine non ruotata e i dati di Google Cloud.
- Anteprima: l'output dei metadati viene fornito in modo che la rotazione del target
la risoluzione del problema è nota utilizzando
Preview.getTargetRotation()
- ImageAnalysis: l'output dei metadati viene fornito in modo che il buffer di immagine le coordinate sono note rispetto alle coordinate di visualizzazione.
- Image Capture: i metadati EXIF dell'immagine, il buffer o entrambi i valori dei metadati vengono modificati in modo da notare l'impostazione di rotazione. Il valore è stato modificato dipende dall'implementazione dell'HAL.
Ritaglia rettangolo
Per impostazione predefinita, il rettangolo di ritaglio è l'intero rettangolo buffer. Puoi personalizzarlo con
ViewPort
e
UseCaseGroup
. Raggruppando l'utilizzo
casi e impostando l'area visibile, CameraX garantisce che i retti di ritaglio
i casi d'uso del gruppo puntano alla stessa area nel sensore della videocamera.
Il seguente snippet di codice mostra come utilizzare questi due corsi:
Kotlin
val viewPort = ViewPort.Builder(Rational(width, height), display.rotation).build() val useCaseGroup = UseCaseGroup.Builder() .addUseCase(preview) .addUseCase(imageAnalysis) .addUseCase(imageCapture) .setViewPort(viewPort) .build() cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, useCaseGroup)
Java
ViewPort viewPort = new ViewPort.Builder( new Rational(width, height), getDisplay().getRotation()).build(); UseCaseGroup useCaseGroup = new UseCaseGroup.Builder() .addUseCase(preview) .addUseCase(imageAnalysis) .addUseCase(imageCapture) .setViewPort(viewPort) .build(); cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, useCaseGroup);
ViewPort
definisce il rettangolo del buffer visibile agli utenti finali. Quindi, CameraX calcola
il rettangolo di ritaglio più grande possibile in base alle proprietà dell'area visibile e
e altri casi d'uso correlati. Di solito, per ottenere un effetto WYSIWYG, puoi configurare
l'area visibile in base al caso d'uso dell'anteprima. Un modo semplice per ottenere l'area visibile
per utilizzare PreviewView
.
I seguenti snippet di codice mostrano come ottenere l'oggetto ViewPort
:
Kotlin
val viewport = findViewById<PreviewView>(R.id.preview_view).viewPort
Java
ViewPort viewPort = ((PreviewView)findViewById(R.id.preview_view)).getViewPort();
Nell'esempio precedente, i dati che l'app riceve da ImageAnalysis
e
ImageCapture
corrisponde a ciò che l'utente finale vede in PreviewView
, supponendo che
Il tipo di scala di PreviewView
è impostato sul valore predefinito, FILL_CENTER
. Dopo l'applicazione
il rettangolo di ritaglio e la rotazione nel buffer di output, l'immagine di tutti i casi d'uso
è lo stesso, anche se probabilmente con risoluzioni diverse. Per ulteriori informazioni
su come applicare le informazioni sulla trasformazione, consulta Trasformare
come output.
Selezione fotocamera
CameraX seleziona automaticamente la fotocamera migliore per la tua applicazione requisiti e casi d'uso. Se vuoi utilizzare un dispositivo diverso da quello selezionate per te, hai a disposizione alcune opzioni:
- Richiedi la fotocamera anteriore predefinita con
CameraSelector.DEFAULT_FRONT_CAMERA
- Richiedi la fotocamera posteriore predefinita con
CameraSelector.DEFAULT_BACK_CAMERA
- Filtra l'elenco dei dispositivi disponibili in base alla relativa
CameraCharacteristics
conCameraSelector.Builder.addCameraFilter()
.
Il seguente esempio di codice illustra come creare un CameraSelector
per
influenzare la selezione del dispositivo:
Kotlin
fun selectExternalOrBestCamera(provider: ProcessCameraProvider):CameraSelector? { val cam2Infos = provider.availableCameraInfos.map { Camera2CameraInfo.from(it) }.sortedByDescending { // HARDWARE_LEVEL is Int type, with the order of: // LEGACY < LIMITED < FULL < LEVEL_3 < EXTERNAL it.getCameraCharacteristic(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) } return when { cam2Infos.isNotEmpty() -> { CameraSelector.Builder() .addCameraFilter { it.filter { camInfo -> // cam2Infos[0] is either EXTERNAL or best built-in camera val thisCamId = Camera2CameraInfo.from(camInfo).cameraId thisCamId == cam2Infos[0].cameraId } }.build() } else -> null } } // create a CameraSelector for the USB camera (or highest level internal camera) val selector = selectExternalOrBestCamera(processCameraProvider) processCameraProvider.bindToLifecycle(this, selector, preview, analysis)
Seleziona più videocamere contemporaneamente
A partire da CameraX 1.3, puoi anche selezionare più fotocamere contemporaneamente. Ad esempio, puoi eseguire l'associazione a una fotocamera anteriore e posteriore per scattare foto o registrare video da entrambe le prospettive.
Quando si utilizza la funzione Fotocamera simultanea, il dispositivo può attivare due videocamere
con obiettivi diversi contemporaneamente o utilizza due fotocamere posteriori
contemporaneamente. Il seguente blocco di codice mostra come impostare due videocamere quando
chiamata a bindToLifecycle
e come ottenere entrambi gli oggetti Camera dall'oggetto
Oggetto ConcurrentCamera
.
Kotlin
// Build ConcurrentCameraConfig val primary = ConcurrentCamera.SingleCameraConfig( primaryCameraSelector, useCaseGroup, lifecycleOwner ) val secondary = ConcurrentCamera.SingleCameraConfig( secondaryCameraSelector, useCaseGroup, lifecycleOwner ) val concurrentCamera = cameraProvider.bindToLifecycle( listOf(primary, secondary) ) val primaryCamera = concurrentCamera.cameras[0] val secondaryCamera = concurrentCamera.cameras[1]
Java
// Build ConcurrentCameraConfig SingleCameraConfig primary = new SingleCameraConfig( primaryCameraSelector, useCaseGroup, lifecycleOwner ); SingleCameraConfig secondary = new SingleCameraConfig( primaryCameraSelector, useCaseGroup, lifecycleOwner ); ConcurrentCamera concurrentCamera = mCameraProvider.bindToLifecycle(Arrays.asList(primary, secondary)); Camera primaryCamera = concurrentCamera.getCameras().get(0); Camera secondaryCamera = concurrentCamera.getCameras().get(1);
Risoluzione fotocamera
Puoi scegliere di consentire a CameraX di impostare la risoluzione dell'immagine in base a una combinazione delle funzionalità del dispositivo, l'hardware supportato del dispositivo livello, caso d'uso e le proporzioni fornite. In alternativa, puoi impostare una specifica risoluzione target o proporzioni specifiche nei casi d'uso che supportano configurazione.
Risoluzione automatica
CameraX è in grado di determinare automaticamente le migliori impostazioni di risoluzione in base al
specifici dei casi d'uso specificati in cameraProcessProvider.bindToLifecycle()
. Sempre
è possibile specificare tutti i casi d'uso necessari per l'esecuzione simultanea in
in una singola chiamata bindToLifecycle()
. FotocameraX determina le risoluzioni
in base all'insieme di casi d'uso legati al supporto del dispositivo
livello di hardware e tenendo conto della varianza specifica del dispositivo (quando
supera o non soddisfa le configurazioni di stream
disponibile).
Lo scopo è consentire l'esecuzione dell'applicazione su una vasta gamma di dispositivi mentre
minimizzando i percorsi di codice specifici del dispositivo.
Le proporzioni predefinite per i casi d'uso di acquisizione e analisi delle immagini sono 4:3.
I casi d'uso prevedono proporzioni configurabili per consentire all'applicazione di specificare le proporzioni desiderate in base al design della UI. L'output di CameraX viene prodotto devono corrispondere alle proporzioni richieste, quanto più supportate dal dispositivo. Se c'è nessuna risoluzione con corrispondenza esatta supportata, quella che soddisfa il maggior numero di condizioni è selezionata. Di conseguenza, l'applicazione determina come viene visualizzata la videocamera app e CameraX determina le migliori impostazioni di risoluzione della fotocamera per soddisfare su dispositivi diversi.
Ad esempio, un'app può effettuare le seguenti operazioni:
- Specifica una risoluzione target pari a 4:3 o 16:9 per un caso d'uso
- Specifica una risoluzione personalizzata, che CameraX tenta di trovare il più vicino abbina a
- Specifica le proporzioni di ritaglio per
ImageCapture
CameraX sceglie automaticamente le risoluzioni della superficie interna di Camera2. La la seguente tabella mostra le risoluzioni:
Caso d'uso | Risoluzione della superficie interna | Risoluzione dei dati di output |
---|---|---|
Anteprima | Proporzioni:la risoluzione che meglio si adatta al target al dell'ambientazione. | Risoluzione della superficie interna. Vengono forniti metadati per consentire un ritaglio, scalare e ruotare per le proporzioni target. |
Risoluzione predefinita:la risoluzione di anteprima più alta o la più alta preferita in base al dispositivo che corrisponda alle proporzioni dell'anteprima. | ||
Risoluzione massima: dimensione dell'anteprima, che si riferisce alla dimensione migliore in base alla risoluzione dello schermo del dispositivo o a 1080p (1920 x 1080), a seconda di quale sia il valore più piccolo. | ||
Analisi delle immagini | Proporzioni:la risoluzione che meglio si adatta al target al dell'ambientazione. | Risoluzione della superficie interna. |
Risoluzione predefinita: l'impostazione di risoluzione target predefinita è 640x480. Regolazione della risoluzione target e delle proporzioni corrispondenti offre una risoluzione più supportata. | ||
Risoluzione massima:la risoluzione di uscita massima del dispositivo della videocamera, pari a
YUV_420_888 che viene recuperato da
StreamConfigurationMap.getOutputSizes()
Per impostazione predefinita, la risoluzione target è impostata su 640 x 480; pertanto, se si desidera una risoluzione superiore a 640 x 480, è necessario utilizzare
setTargetResolution()
e
setTargetAspectRatio()
per ottenere quello più vicino tra le risoluzioni supportate.
|
||
Acquisizione di immagini | Proporzioni:il formato che meglio si adatta all'impostazione. | Risoluzione della superficie interna. |
Risoluzione predefinita:la risoluzione più alta disponibile o la più alta. una risoluzione preferita dal dispositivo che corrisponda alle proporzioni di Image Capture. | ||
Risoluzione massima:la risoluzione massima di output del dispositivo della videocamera in
in formato JPEG. Utilizza le funzionalità di
StreamConfigurationMap.getOutputSizes()
per recuperarlo.
|
Specifica una risoluzione
Puoi impostare risoluzioni specifiche quando crei casi d'uso utilizzando
setTargetResolution(Size resolution)
, come mostrato nel seguente codice
esempio:
Kotlin
val imageAnalysis = ImageAnalysis.Builder() .setTargetResolution(Size(1280, 720)) .build()
Java
ImageAnalysis imageAnalysis = new ImageAnalysis.Builder() .setTargetResolution(new Size(1280, 720)) .build();
Non puoi impostare sia le proporzioni che la risoluzione target nello stesso utilizzo
per verificare se è così. In questo modo viene generato un IllegalArgumentException
durante la creazione della configurazione
.
Indica la risoluzione Size
nella coordinata
frame dopo la rotazione delle dimensioni supportate dalla rotazione target. Ad esempio, un
dispositivo con orientamento naturale verticale nella rotazione del target che richiede una
per l'immagine verticale è possibile specificare una dimensione di 480 x 640, e lo stesso dispositivo, ruotato di 90 gradi e
L'orientamento orizzontale del targeting può specificare 640 x 480.
La risoluzione target tenta di stabilire un limite minimo per l'immagine risoluzione del problema. La risoluzione effettiva dell'immagine è la risoluzione più simile disponibile di dimensioni non inferiori alla risoluzione target, come stabilito dal Implementazione della videocamera.
Tuttavia, se non esiste una risoluzione uguale o
maggiore della risoluzione target, la risoluzione più prossima disponibile minore di
viene scelta la risoluzione target. Risoluzioni con le stesse proporzioni di
agli elementi Size
forniti viene assegnata una priorità maggiore rispetto alle risoluzioni di diverse risoluzioni
proporzioni.
CameraX applica la risoluzione più adatta in base alle richieste. Se
la tua esigenza principale è soddisfare le proporzioni, specifica solo setTargetAspectRatio
,
e CameraX determina una risoluzione specifica adatta al dispositivo.
Se la necessità principale dell'app è specificare una risoluzione per rendere l'immagine
l'elaborazione in modo più efficiente (ad esempio, un'immagine di piccole o medie dimensioni basata
funzionalità di elaborazione del dispositivo), utilizza setTargetResolution(Size resolution)
.
Se la tua app richiede una risoluzione esatta, consulta la tabella all'interno
createCaptureSession()
per stabilire quali risoluzioni massime sono supportate da ciascun livello hardware. A
verificare le risoluzioni specifiche supportate dal dispositivo corrente, vedi
StreamConfigurationMap.getOutputSizes(int)
Se la tua app utilizza Android 10 o versioni successive, puoi usare
isSessionConfigurationSupported()
per verificare un determinato SessionConfiguration
.
Controlla l'output della videocamera
Oltre a consentirti di configurare l'output della videocamera in base alle tue esigenze per ogni caso d'uso individuale, CameraX implementa anche le seguenti interfacce per supportare operazioni della fotocamera comuni a tutti i casi d'uso correlati:
CameraControl
ti consente di configurare le funzionalità comuni della fotocamera.CameraInfo
consente di eseguire query gli stati di queste comuni funzionalità della fotocamera.
Di seguito sono riportate le funzionalità della fotocamera supportate con CameraControl:
- Zoom
- Torcia
- Messa a fuoco e misurazione esposimetrica (tocca per mettere a fuoco)
- Compensazione dell'esposizione
Recuperare istanze di CameraControl e CameraInfo
Recupera le istanze di CameraControl
e CameraInfo
utilizzando il metodo
Oggetto Camera
restituito da
ProcessCameraProvider.bindToLifecycle()
.
Il seguente codice mostra un esempio:
Kotlin
val camera = processCameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview) // For performing operations that affect all outputs. val cameraControl = camera.cameraControl // For querying information and states. val cameraInfo = camera.cameraInfo
Java
Camera camera = processCameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview) // For performing operations that affect all outputs. CameraControl cameraControl = camera.getCameraControl() // For querying information and states. CameraInfo cameraInfo = camera.getCameraInfo()
Ad esempio, puoi inviare lo zoom e altre operazioni CameraControl
dopo
chiamata al numero bindToLifecycle()
. Dopo aver interrotto o eliminato l'attività utilizzata per vincolare
dall'istanza della fotocamera, CameraControl
non può più eseguire operazioni
restituisce un errore ListenableFuture
.
Zoom
CameraControl offre due metodi per modificare il livello di zoom:
setZoomRatio()
consente di impostare lo zoom in base al rapporto di zoom.Il rapporto deve essere compreso nell'intervallo
CameraInfo.getZoomState().getValue().getMinZoomRatio()
eCameraInfo.getZoomState().getValue().getMaxZoomRatio()
. In caso contrario, restituisce un valoreListenableFuture
non riuscito.setLinearZoom()
imposta lo zoom corrente con un valore di zoom lineare che va da 0 a 1,0.Il vantaggio dello zoom lineare è che rende il campo visivo (FOV) scala con modifiche allo zoom. Per questo è ideale per l'uso con
Slider
.
CameraInfo.getZoomState()
restituisce un valore LiveData dello stato di zoom corrente. Il valore cambia quando la fotocamera
viene inizializzato o se il livello di zoom viene impostato utilizzando setZoomRatio()
o
setLinearZoom()
. Se chiami uno dei due metodi, i valori vengono impostati come
ZoomState.getZoomRatio()
e
ZoomState.getLinearZoom()
.
Ciò è utile se vuoi visualizzare il testo del rapporto di zoom insieme a un dispositivo di scorrimento.
È sufficiente osservare l'LiveData
di ZoomState
per aggiornarli entrambi senza dover effettuare un
e conversione in blocco.
L'elemento ListenableFuture
restituito da entrambe le API offre la possibilità di applicare
di ricevere una notifica quando una richiesta ricorrente con il valore di zoom specificato viene
completata. Inoltre, se imposti un nuovo valore di zoom durante l'operazione precedente
è ancora in esecuzione, ListenableFuture
dell'operazione di zoom precedente non riesce
immediatamente.
Torcia
CameraControl.enableTorch(boolean)
attiva o disattiva la torcia (nota anche come torcia).
CameraInfo.getTorchState()
può essere utilizzato per eseguire una query sullo stato attuale della torcia. Puoi controllare il valore restituito
di
CameraInfo.hasFlashUnit()
per determinare se è disponibile una torcia. In caso contrario, la chiamata
CameraControl.enableTorch(boolean)
fa sì che il valore ListenableFuture
restituito
completa immediatamente con un risultato non riuscito e imposta lo stato della torcia su
TorchState.OFF
.
Quando la torcia è attiva, rimane accesa durante l'acquisizione di foto e video
a prescindere dall'impostazione flashMode. La
flashMode
pollici
ImageCapture
funziona solo quando la torcia è disattivata.
Messa a fuoco e misurazione esposimetrica
CameraControl.startFocusAndMetering()
attiva la messa a fuoco automatica e la misurazione dell'esposizione impostando le regioni di misurazione AF/AE/AWB
in base alla FocusMeteringAction specificata. Questa funzionalità viene spesso utilizzata per implementare
messa a fuoco" in molte applicazioni per fotocamere.
Punto misurazione
Per iniziare, crea
MeteringPoint
con
MeteringPointFactory.createPoint(float x, float y, float
size)
.
Un MeteringPoint
rappresenta un singolo punto della fotocamera
Surface
Vengono memorizzati in un formato normalizzato
in modo che possa essere facilmente convertita in coordinate del sensore per specificare
Regioni AF/AE/AWB.
La dimensione dell'intervallo MeteringPoint
va da 0 a 1, con una dimensione predefinita pari a
0,15f. Quando chiami MeteringPointFactory.createPoint(float x, float y, float
size)
, CameraX crea una regione rettangolare centrata su (x, y)
per il valore
size
.
Il seguente codice mostra come creare un MeteringPoint
:
Kotlin
// Use PreviewView.getMeteringPointFactory if PreviewView is used for preview. previewView.setOnTouchListener((view, motionEvent) -> { val meteringPoint = previewView.meteringPointFactory .createPoint(motionEvent.x, motionEvent.y) … } // Use DisplayOrientedMeteringPointFactory if SurfaceView / TextureView is used for // preview. Please note that if the preview is scaled or cropped in the View, // it’s the application's responsibility to transform the coordinates properly // so that the width and height of this factory represents the full Preview FOV. // And the (x,y) passed to create MeteringPoint might need to be adjusted with // the offsets. val meteringPointFactory = DisplayOrientedMeteringPointFactory( surfaceView.display, camera.cameraInfo, surfaceView.width, surfaceView.height ) // Use SurfaceOrientedMeteringPointFactory if the point is specified in // ImageAnalysis ImageProxy. val meteringPointFactory = SurfaceOrientedMeteringPointFactory( imageWidth, imageHeight, imageAnalysis)
startMetering Focus e ActionMetering
Per richiamare
startFocusAndMetering()
,
per le applicazioni devono creare
FocusMeteringAction
,
che consiste in uno o più MeteringPoints
con modalità di misurazione facoltativa
combinazioni da
FLAG_AF
,
FLAG_AE
,
FLAG_AWB
. La
seguire il codice dimostra questo utilizzo:
Kotlin
val meteringPoint1 = meteringPointFactory.createPoint(x1, x1) val meteringPoint2 = meteringPointFactory.createPoint(x2, y2) val action = FocusMeteringAction.Builder(meteringPoint1) // default AF|AE|AWB // Optionally add meteringPoint2 for AF/AE. .addPoint(meteringPoint2, FLAG_AF | FLAG_AE) // The action is canceled in 3 seconds (if not set, default is 5s). .setAutoCancelDuration(3, TimeUnit.SECONDS) .build() val result = cameraControl.startFocusAndMetering(action) // Adds listener to the ListenableFuture if you need to know the focusMetering result. result.addListener({ // result.get().isFocusSuccessful returns if the auto focus is successful or not. }, ContextCompat.getMainExecutor(this)
Come mostrato nel codice precedente,
startFocusAndMetering()
prende un FocusMeteringAction
composto da un MeteringPoint
per AF/AE/AWB
di misurazione esposimetrica e un altro punto di misurazione solo per AF e AE.
Internamente, CameraX la converte in Fotocamera2
MeteringRectangles
e imposta le parole chiave corrispondenti
CONTROL_AF_REGIONS
/
CONTROL_AE_REGIONS
/
CONTROL_AWB_REGIONS
parametri alla richiesta di acquisizione.
Poiché non tutti i dispositivi supportano AF/AE/AWB e più regioni, CameraX esegue
il FocusMeteringAction
con il massimo impegno. FotocameraX utilizza il numero massimo di
di MeteringPoints supportati, nell'ordine in cui sono stati aggiunti i punti. Tutti
I MeteringPoint aggiunti dopo il conteggio massimo vengono ignorati. Ad esempio, se un
FocusMeteringAction
viene fornito con 3 MeteringPoints su una piattaforma che supporta
solo 2, vengono usati solo i primi 2 MeteringPoints. L'ultimo valore di MeteringPoint
è
ignorato da CameraX.
Compensazione dell'esposizione
La compensazione dell'esposizione è utile quando le applicazioni hanno bisogno di regolare l'esposizione di valore (EV) oltre il risultato di esposizione automatica (AE). Compensazione dell'esposizione vengono combinati nel seguente modo per determinare l'esposizione necessaria per condizioni attuali dell'immagine:
Exposure = ExposureCompensationIndex * ExposureCompensationStep
CameraX offre
Camera.CameraControl.setExposureCompensationIndex()
per impostare la compensazione dell'esposizione come valore di indice.
I valori di indice positivi rendono l'immagine più luminosa, mentre quelli negativi attenuano la luminosità
dell'immagine. Le applicazioni possono eseguire query sull'intervallo supportato
CameraInfo.ExposureState.exposureCompensationRange()
descritti nella prossima sezione. Se il valore è supportato, il valore restituito
ListenableFuture
viene completato quando il valore viene abilitato correttamente nel
richiesta di acquisizione; Se l'indice specificato non rientra nell'intervallo supportato,
setExposureCompensationIndex()
fa sì che l'oggetto ListenableFuture
restituito
viene completata immediatamente con un risultato non riuscito.
CameraX conserva solo l'ultima versione in sospeso di setExposureCompensationIndex()
e chiamando la funzione più volte prima della richiesta precedente
e l'esecuzione ne porta all'annullamento.
Lo snippet riportato di seguito imposta un indice di compensazione dell'esposizione e registra un callback per quando è stata eseguita la richiesta di modifica dell'esposizione:
Kotlin
camera.cameraControl.setExposureCompensationIndex(exposureCompensationIndex) .addListener({ // Get the current exposure compensation index, it might be // different from the asked value in case this request was // canceled by a newer setting request. val currentExposureIndex = camera.cameraInfo.exposureState.exposureCompensationIndex … }, mainExecutor)
Camera.CameraInfo.getExposureState()
recupera lo statoExposureState
tra cui:- Supporta il controllo della compensazione dell'esposizione.
- L'indice di compensazione dell'esposizione corrente.
- L'intervallo dell'indice di compensazione dell'esposizione.
- L'intervallo di compensazione dell'esposizione utilizzato nel valore di compensazione dell'esposizione calcolo.
Ad esempio, il seguente codice inizializza le impostazioni per un'esposizione
SeekBar
con ExposureState
attuale
valori:
Kotlin
val exposureState = camera.cameraInfo.exposureState binding.seekBar.apply { isEnabled = exposureState.isExposureCompensationSupported max = exposureState.exposureCompensationRange.upper min = exposureState.exposureCompensationRange.lower progress = exposureState.exposureCompensationIndex }
Risorse aggiuntive
Per saperne di più su CameraX, consulta le risorse aggiuntive che seguono.
Codelab
Esempio di codice
Community di sviluppatori
Gruppo di discussione di Android CameraX