Sie konfigurieren jeden CameraX-Anwendungsfall so, dass unterschiedliche Aspekte der Verwendung gesteuert werden. die Vorgänge in der Anfrage auszuführen.
Für den Anwendungsfall „Bilderfassung“ können Sie beispielsweise ein Zielseitenverhältnis festlegen und einen Blitzmodus. Der folgende Code zeigt ein Beispiel:
Kotlin
val imageCapture = ImageCapture.Builder() .setFlashMode(...) .setTargetAspectRatio(...) .build()
Java
ImageCapture imageCapture = new ImageCapture.Builder() .setFlashMode(...) .setTargetAspectRatio(...) .build();
Neben den Konfigurationsoptionen werden in einigen Anwendungsfällen APIs auch für Einstellungen nach der Erstellung des Anwendungsfalls ändern. Informationen zu eine Konfiguration, die für den jeweiligen Anwendungsfall spezifisch ist, finden Sie unter Implementierung eines „preview“, „Analysieren“ Bilder und Bild aufnehmen.
CameraXConfig
Der Einfachheit halber hat CameraX Standardkonfigurationen, z. B. interne Executors.
und Handler, die für die meisten
Nutzungsszenarien geeignet sind. Wenn Ihre
Anwendung spezielle Anforderungen hat oder diese anpassen möchte
Konfigurationen, CameraXConfig
ist die Schnittstelle für diesen Zweck.
Mit CameraXConfig
kann eine Anwendung Folgendes tun:
- Optimieren Sie die Startlatenz mit
setAvailableCameraLimiter()
- Stellen Sie den Executor der Anwendung für CameraX mit
setCameraExecutor()
- Ersetzen Sie den Standard-Planer-Handler durch
setSchedulerHandler()
- Protokollierungsebene ändern mit
setMinimumLoggingLevel()
Nutzungsmodell
Im Folgenden wird die Verwendung von CameraXConfig
beschrieben:
- Erstellen Sie ein
CameraXConfig
-Objekt mit Ihren benutzerdefinierten Konfigurationen. - Implementieren Sie die
CameraXConfig.Provider
in derApplication
undCameraXConfig
-Objekt zurückgeben ingetCameraXConfig()
- Fügen Sie der Datei
AndroidManifest.xml
die KlasseApplication
hinzu als hier beschrieben.
Das folgende Codebeispiel beschränkt die CameraX-Protokollierung auf Fehler. Nur Nachrichten:
Kotlin
class CameraApplication : Application(), CameraXConfig.Provider { override fun getCameraXConfig(): CameraXConfig { return CameraXConfig.Builder.fromConfig(Camera2Config.defaultConfig()) .setMinimumLoggingLevel(Log.ERROR).build() } }
Speichern Sie eine lokale Kopie des CameraXConfig
-Objekts, wenn Ihre Anwendung
die Konfiguration von CameraX kennen.
Kamerabegrenzer
Beim ersten Aufruf von
ProcessCameraProvider.getInstance()
,
CameraX listet die Eigenschaften der auf der Kamera verfügbaren Kameras auf und fragt diese ab.
. Da CameraX mit Hardwarekomponenten kommunizieren muss,
kann für jede Kamera sehr viel Zeit in Anspruch nehmen, insbesondere
Low-End-Geräte. Wenn Ihre App nur bestimmte Kameras auf dem Gerät verwendet,
wie der Standard-Frontkamera, können Sie CameraX so einstellen, dass
andere Kameras ignoriert werden.
wodurch die Startlatenz für die von Ihrer Anwendung verwendeten Kameras reduziert werden kann.
Wenn CameraSelector
bestanden wurde
bis
CameraXConfig.Builder.setAvailableCamerasLimiter()
filtert eine Kamera heraus, verhält sich CameraX so, als wäre diese Kamera nicht vorhanden. Für
Beispiel: Der folgende Code schränkt ein, dass die App nur die
Standard-Rückkamera:
Kotlin
class MainApplication : Application(), CameraXConfig.Provider { override fun getCameraXConfig(): CameraXConfig { return CameraXConfig.Builder.fromConfig(Camera2Config.defaultConfig()) .setAvailableCamerasLimiter(CameraSelector.DEFAULT_BACK_CAMERA) .build() } }
Threads
Viele Plattform-APIs, auf denen CameraX basiert, müssen blockiert werden.
Interprocess Communication (IPC) mit Hardware kann manchmal Hunderte
von Millisekunden, um zu antworten. Aus diesem Grund ruft CameraX diese APIs nur von
Hintergrundthreads, damit der Hauptthread nicht blockiert wird
bleibt flüssig. CameraX verwaltet diese Hintergrundthreads intern,
das Verhalten transparent zu sein scheint. Einige Anwendungen erfordern jedoch
eine strenge Kontrolle.
von Threads. Mit CameraXConfig
kann eine Anwendung die Hintergrundthreads festlegen
die durch
CameraXConfig.Builder.setCameraExecutor()
und
CameraXConfig.Builder.setSchedulerHandler()
Kamera-Executor
Der Camera Executor wird für alle internen API-Aufrufe der Kameraplattform sowie
Callbacks von diesen APIs: CameraX weist ein internes
Executor
, um diese Aufgaben auszuführen.
Wenn Ihre Anwendung jedoch eine strengere Steuerung von Threads erfordert, verwenden Sie
CameraXConfig.Builder.setCameraExecutor()
Planer-Handler
Mit dem Scheduler-Handler werden interne Aufgaben in festen Intervallen geplant,
z. B. einen neuen Versuch starten, die Kamera zu öffnen, wenn sie nicht verfügbar ist. Dieser Handler tut
keine Jobs ausführen und nur an den Kamera-Executor weitergeleitet werden. Es ist auch
werden manchmal auf Legacy-API-Plattformen verwendet, die eine
Handler
für Callbacks In diesen Fällen
Callbacks werden weiterhin nur direkt an den Camera Executor gesendet. KameraX
teilt und verwaltet ein internes
HandlerThread
zum Ausführen dieser Aufgaben
aber Sie können ihn mit CameraXConfig.Builder.setSchedulerHandler()
überschreiben.
Protokollierung
Mit der CameraX-Protokollierung können Anwendungen Logcat-Nachrichten filtern. um ausführliche Meldungen in Ihrem Produktionscode zu vermeiden. CameraX unterstützt vier Protokollierungsstufen, von der ausführlichsten bis zur schwerwiegendsten:
Log.DEBUG
(Standard)Log.INFO
Log.WARN
Log.ERROR
Weitere Informationen finden Sie in der Android-Protokolldokumentation.
finden Sie detaillierte Beschreibungen dieser Protokollebenen. Verwenden Sie
CameraXConfig.Builder.setMinimumLoggingLevel(int)
um die entsprechende Logging-Ebene für Ihre Anwendung festzulegen.
Automatische Auswahl
CameraX bietet automatisch gerätespezifische Funktionen. auf denen Ihre App ausgeführt wird. Beispielsweise erkennt CameraX automatisch, ist die beste Auflösung, wenn du keine Auflösung angibst wird nicht unterstützt. All dies wird von der Bibliothek übernommen, Sie müssen gerätespezifischen Code schreiben.
Das Ziel von CameraX ist es, eine Kamerasitzung erfolgreich zu initialisieren. Das bedeutet, Bei CameraX werden Auflösung und Seitenverhältnisse je nach Gerätefähigkeit gefährden. Das kann folgende Gründe haben:
- Das Gerät unterstützt die angeforderte Auflösung nicht.
- Das Gerät hat Kompatibilitätsprobleme, z. B. ältere Geräte, für die eine damit alles korrekt funktioniert.
- Auf einigen Geräten sind bestimmte Formate nur in bestimmten Seitenverhältnissen verfügbar Seitenverhältnissen.
- Das Gerät hat eine Präferenz für „nächstgelegene mod16“. für JPEG oder Video
Codierung. Weitere Informationen finden Sie unter
SCALER_STREAM_CONFIGURATION_MAP
Auch wenn CameraX die Sitzung erstellt und verwaltet, sollten Sie in jedem Fall die zurückgegebene Bildgrößen in der Ausgabe des Anwendungsfalls in Ihrem Code und passen Sie sie entsprechend an.
Ausrichtung
Standardmäßig ist die Kameradrehung so eingestellt, dass sie der Drehung des Standarddisplays entspricht bei der Erstellung des Anwendungsfalls. In diesem Standardfall erstellt CameraX damit die App dem entspricht, was Sie in der in der Vorschau ansehen. Sie können die Rotation in einen benutzerdefinierten Wert ändern, um Multi-Display-Anzeigen zu unterstützen Geräte durch Übergeben der aktuellen Displayausrichtung beim Konfigurieren des Anwendungsfalls oder dynamisch, nachdem sie erstellt wurden.
Ihre App kann die Zielrotation mithilfe von Konfigurationseinstellungen festlegen. Es kann dann
Rotationseinstellungen mithilfe der Methoden aus den APIs für Anwendungsfälle (z. B.
ImageAnalysis.setTargetRotation()
)
auch wenn der Lebenszyklus
ausgeführt ist. Sie können diese Funktion nutzen,
ist auf Hochformat eingestellt – eine Neukonfiguration findet
gedreht werden soll. Der Anwendungsfall von Foto oder Analyse muss jedoch die
aktuelle Drehung des Geräts. Beispielsweise kann die Rotationserkennung erforderlich sein.
also
Gesichter sind für die Gesichtserkennung korrekt ausgerichtet oder Fotos sind im Querformat eingestellt
oder Hochformat.
Daten für erfasste Bilder werden möglicherweise ohne Rotationsinformationen gespeichert. EXIF-Daten enthält Rotationsinformationen, sodass Galerieanwendungen das Bild in nach dem Speichern in die richtige Ausrichtung.
Um Vorschaudaten mit der richtigen Ausrichtung anzuzeigen, können Sie die Metadaten verwenden
Ausgabe von
Preview.PreviewOutput()
um Transformationen zu erstellen.
Das folgende Codebeispiel zeigt, wie die Rotation für ein Ausrichtungsereignis festgelegt wird:
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(); }
Basierend auf der festgelegten Rotation werden in jedem Anwendungsfall entweder die Bilddaten gedreht direkt oder stellt den Nutzern des nicht gedrehten Bildes Rotationsmetadaten bereit Daten.
- Vorschau: Die Metadatenausgabe wird bereitgestellt, sodass die Rotation des Ziels
ist die Verwendung von
Preview.getTargetRotation()
- ImageAnalysis: Die Metadatenausgabe wird für den Bildzwischenspeicher bereitgestellt. -Koordinaten relativ zu Anzeigekoordinaten bekannt sind.
- ImageCapture: Die Metadaten des EXIF-Bilds, der Zwischenspeicher oder beides. Metadaten werden so geändert, dass die Rotationseinstellung angegeben wird. Der geänderte Wert hängt von der HAL-Implementierung ab.
Rechteck zuschneiden
Standardmäßig entspricht das Rechteck zuschneiden dem vollständigen Zwischenspeicher. Sie können sie anpassen mit
ViewPort
und
UseCaseGroup
Nach Gruppierung
und beim Festlegen des Darstellungsbereichs sorgt CameraX dafür, dass der Zuschnitt
die Anwendungsfälle in der Gruppe auf denselben Bereich im Kamerasensor verweisen.
Das folgende Code-Snippet zeigt, wie diese beiden Klassen verwendet werden:
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
definiert das Zwischenspeicherrechteck, das für Endnutzer sichtbar ist. Dann berechnet CameraX
Größtmögliches Zuschneide-Rechteck basierend auf den Eigenschaften des Darstellungsbereichs und des
angehängten Anwendungsfälle. Um einen WYSIWYG-Effekt zu erzielen, können Sie
Darstellungsbereich basierend auf
dem Anwendungsfall der Vorschau. Eine einfache Methode zum Abrufen des Darstellungsbereichs
, um PreviewView
zu verwenden.
Die folgenden Code-Snippets zeigen, wie das Objekt ViewPort
abgerufen wird:
Kotlin
val viewport = findViewById<PreviewView>(R.id.preview_view).viewPort
Java
ViewPort viewPort = ((PreviewView)findViewById(R.id.preview_view)).getViewPort();
Im vorherigen Beispiel wird der Inhalt der App von ImageAnalysis
und
ImageCapture
entspricht dem, was der Endnutzer in PreviewView
sieht, vorausgesetzt, der
Der Skalierungstyp von PreviewView
ist auf die Standardeinstellung FILL_CENTER
festgelegt. Nach dem Anwenden
Zuschnitt und Drehung zum Ausgabezwischenspeicher, das Bild aus allen Anwendungsfällen
mit unterschiedlicher Auflösung. Weitere Informationen
Informationen zum Anwenden der Transformationsinformationen finden Sie unter Transformieren
Output
Kameraauswahl
CameraX wählt automatisch das beste Kameragerät für die Anforderungen und Anwendungsfälle. Wenn Sie ein anderes Gerät als dieses verwenden möchten stehen Ihnen mehrere Optionen zur Verfügung:
- Standard-Frontkamera anfordern mit
CameraSelector.DEFAULT_FRONT_CAMERA
- Standardrückkamera anfordern mit
CameraSelector.DEFAULT_BACK_CAMERA
- Liste der verfügbaren Geräte nach ihrem
CameraCharacteristics
mitCameraSelector.Builder.addCameraFilter()
Das folgende Codebeispiel zeigt, wie Sie eine CameraSelector
erstellen, um
Geräteauswahl beeinflussen:
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)
Mehrere Kameras gleichzeitig auswählen
Ab CameraX 1.3 können Sie auch mehrere Kameras gleichzeitig auswählen. Sie können beispielsweise eine Bindung an eine Front- und Rückkamera herstellen, um Fotos oder Aufnahmen zu machen aus beiden Perspektiven gleichzeitig ansehen.
Bei Verwendung der Funktion „Gleichzeitige Kamera“ können zwei Kameras bedient werden.
mit unterschiedlichen Objektiven gleichzeitig oder zwei Kameras auf der Rückseite
gleichzeitig. Der folgende Codeblock zeigt, wie zwei Kameras eingerichtet werden,
bindToLifecycle
aufrufen und beide Camera-Objekte aus der zurückgegebenen
ConcurrentCamera
-Objekt.
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);
Kameraauflösung
Sie können festlegen, dass KameraX die Bildauflösung anhand einer Kombination festlegen soll. der Gerätefunktionen, der unterstützten Hardware Level, Anwendungsfall und angegebenes Seitenverhältnis. Alternativ können Sie ein bestimmtes die Zielauflösung oder ein bestimmtes Seitenverhältnis haben. Konfiguration.
Automatische Auflösung
CameraX kann die beste Auflösung automatisch anhand des
Anwendungsfälle, die in cameraProcessProvider.bindToLifecycle()
angegeben sind. Immer
geben Sie alle Anwendungsfälle an, die gleichzeitig in einem einzigen
Sitzung in einem einzelnen bindToLifecycle()
-Aufruf. CameraX bestimmt die Auflösung.
basierend auf den Anwendungsfällen, für die die unterstützte
Hardwareebene und unter Berücksichtigung gerätespezifischer Abweichungen (wenn ein Gerät
die Stream-Konfigurationen überschreitet oder nicht erfüllt
verfügbar).
Die App soll auf einer Vielzahl von Geräten laufen,
und minimieren gerätespezifische Codepfade.
Das Standardseitenverhältnis für die Bilderfassung und ‐analyse beträgt 4:3.
Anwendungsfälle haben ein konfigurierbares Seitenverhältnis, über das die Anwendung festlegen kann das gewünschte Seitenverhältnis basierend auf dem UI-Design. Die Ausgabe von CameraX wird Sie müssen den angeforderten Seitenverhältnissen so genau wie das Gerät entsprechen. Wenn es keine genaue Übereinstimmung unterstützt, die die meisten Bedingungen erfüllt ausgewählt ist. Die Anwendung gibt also vor, wie die Kamera im App und CameraX ermittelt die beste Kameraauflösung, auf verschiedenen Geräten.
Eine App kann beispielsweise Folgendes tun:
- Geben Sie für einen Anwendungsfall eine Zielauflösung von 4:3 oder 16:9 an
- Geben Sie eine benutzerdefinierte Auflösung an, die CameraX versucht, die nächstgelegene Auflösung zu finden Übereinstimmung mit
- Seitenverhältnis für den Zuschnitt für
ImageCapture
angeben
CameraX wählt die Oberflächenauflösungen von Camera2 automatisch aus. Die Folgende Tabelle zeigt die Auflösungen:
Anwendungsfall | Interne Oberflächenauflösung | Auflösung der Ausgabedaten |
---|---|---|
Vorschau | Seitenverhältnis: Das ist die Auflösung, die am besten für das Ziel und den Einstellung. | Interne Oberflächenauflösung. Metadaten werden bereitgestellt, damit eine Ansicht das Zuschneiden, das für das gewünschte Seitenverhältnis skalieren und drehen. |
Standardauflösung:Höchste Vorschauauflösung oder höchste Auflösung des Geräts, die dem Seitenverhältnis der Vorschau entspricht. | ||
Maximale Auflösung:Vorschaugröße, die sich auf die beste Größe bezieht Bildschirmauflösung des Geräts oder 1080p (1920 x 1080) entsprechen, je nachdem, welcher Wert kleiner ist. | ||
Bildanalyse | Seitenverhältnis:Das ist die Auflösung, die am besten zum Ziel passt. Einstellung. | Interne Oberflächenauflösung. |
Standardauflösung:Die Standardeinstellung für die Zielauflösung ist 640x480. Zielauflösung und entsprechendes Seitenverhältnis anpassen zu einer am besten unterstützten Auflösung führt. | ||
Maximale Auflösung:Die maximale Ausgabeauflösung der Kamera von
YUV_420_888-Format, das abgerufen wird aus
StreamConfigurationMap.getOutputSizes()
Die Zielauflösung ist standardmäßig auf 640 x 480 festgelegt. Wenn Sie also eine höhere Auflösung als 640 x 480 wünschen, müssen Sie
setTargetResolution()
und
setTargetAspectRatio()
um die beste Auflösung zu finden.
|
||
Bildaufnahme | Seitenverhältnis:Das am besten zur Einstellung passende Seitenverhältnis. | Interne Oberflächenauflösung. |
Standardauflösung:Höchste verfügbare oder höchste Auflösung Auflösung des Geräts, die dem Seitenverhältnis von ImageCapture entspricht. | ||
Maximale Auflösung:Die maximale Ausgabeauflösung der Kamera in
im JPEG-Format. Verwenden Sie
StreamConfigurationMap.getOutputSizes()
um diese Informationen abzurufen.
|
Auflösung angeben
Beim Erstellen von Anwendungsfällen können Sie mithilfe der
setTargetResolution(Size resolution)
-Methode, wie im folgenden Code dargestellt
Beispiel:
Kotlin
val imageAnalysis = ImageAnalysis.Builder() .setTargetResolution(Size(1280, 720)) .build()
Java
ImageAnalysis imageAnalysis = new ImageAnalysis.Builder() .setTargetResolution(new Size(1280, 720)) .build();
Sie können nicht gleichzeitig das Zielseitenverhältnis und die Zielauflösung festlegen
Fall. Dadurch wird beim Erstellen der Konfiguration ein IllegalArgumentException
ausgelöst
-Objekt enthält.
Geben Sie die Auflösung Size
in den Koordinaten an.
nachdem die unterstützten Größen durch die Zieldrehung gedreht wurden. Beispiel:
Gerät mit natürlicher Ausrichtung im Hochformat und natürlicher Zielrotation, das ein
Bild im Hochformat kann 480 x 640 Pixel und dasselbe Gerät, um 90 Grad gedreht, und
Querformat-Targeting kann 640 x 480 angeben.
Mit der Zielauflösung wird versucht, eine Mindestgrenze für das Bild festzulegen Problembehebung. Die tatsächliche Bildauflösung entspricht der aktuellen verfügbaren Auflösung die nicht kleiner als die Zielauflösung ist. Kameraimplementierung
Wenn jedoch keine Auflösung vorhanden ist, die gleich oder
größer als die Zielauflösung ist, ist die nächste verfügbare Auflösung kleiner als
wird die angestrebte Auflösung ausgewählt. Auflösungen mit demselben Seitenverhältnis von
haben die angegebenen Size
eine höhere Priorität als verschiedene Auflösungen
Seitenverhältnissen.
CameraX wendet je nach den Anforderungen die am besten geeignete Auflösung an. Wenn der Parameter
Hauptanforderung besteht darin, das Seitenverhältnis zu erfüllen. Geben Sie nur setTargetAspectRatio
an.
und CameraX eine für das jeweilige Gerät passende Auflösung.
Wenn für die App vor allem die Auflösung zum Erstellen von Bildern erforderlich ist
effizienter zu verarbeiten (z. B. ein kleines oder mittelgroßes Bild basierend auf
Geräteverarbeitungsfunktionen), verwenden Sie setTargetResolution(Size resolution)
.
Falls für Ihre App eine genaue Lösung erforderlich ist, sehen Sie sich die Tabelle unter
createCaptureSession()
um zu ermitteln, welche maximalen Auflösungen von der jeweiligen Hardwarestufe unterstützt werden. Bis
welche Auflösungen vom aktuellen Gerät unterstützt werden, siehe
StreamConfigurationMap.getOutputSizes(int)
Wenn Ihre App unter Android 10 oder höher läuft, können Sie
isSessionConfigurationSupported()
um eine bestimmte SessionConfiguration
zu bestätigen.
Kameraausgabe steuern
Sie können nicht nur die Kameraausgabe für jedes Gerät individuell konfigurieren, für individuelle Anwendungsfälle implementiert CameraX auch die folgenden Schnittstellen, um Kameravorgänge, die für alle gebundenen Anwendungsfälle typisch sind:
- Mit
CameraControl
können Sie Kamerafunktionen konfigurieren - Mit
CameraInfo
können Sie Abfragen die Status dieser gängigen Kamerafunktionen.
Folgende Kamerafunktionen werden von CameraControl unterstützt:
- Zoom
- Fackel
- Fokus und Belichtungsmessung (Zum Fokussieren tippen)
- Belichtungskorrektur
Instanzen von CameraControl und CameraInfo abrufen
Rufen Sie Instanzen von CameraControl
und CameraInfo
mithilfe der
Camera
-Objekt, das von zurückgegeben wird.
ProcessCameraProvider.bindToLifecycle()
Der folgende Code zeigt ein Beispiel:
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()
Sie können beispielsweise Zoom- und andere CameraControl
-Vorgänge senden, nachdem
bindToLifecycle()
wird angerufen. Nachdem Sie die zum Binden verwendete Aktivität beendet oder gelöscht haben
Kamerainstanz hat CameraControl
keine Vorgänge mehr ausführen und
gibt einen fehlgeschlagenen ListenableFuture
zurück.
Zoom
CameraControl bietet zwei Methoden zum Ändern der Zoomstufe:
setZoomRatio()
legt den Zoom um das Zoomverhältnis fest.Das Verhältnis muss im
CameraInfo.getZoomState().getValue().getMinZoomRatio()
undCameraInfo.getZoomState().getValue().getMaxZoomRatio()
. Andernfalls Funktion gibt einen fehlgeschlagenenListenableFuture
zurück.setLinearZoom()
legt die aktuelle Zoomstufe mit einem linearen Zoomwert zwischen 0 und 1,0 fest.Der Vorteil des linearen Zooms besteht darin, dass das Sichtfeld mit Änderungen des Zoomfaktors skalieren. Daher eignet sie sich ideal für
Slider
-Ansicht.
CameraInfo.getZoomState()
gibt LiveData des aktuellen Zoom-Zustands zurück. Der Wert ändert sich, wenn die Kamera
initialisiert ist oder die Zoomstufe mit setZoomRatio()
oder
setLinearZoom()
. Durch das Aufrufen einer der beiden Methoden werden die
ZoomState.getZoomRatio()
und
ZoomState.getLinearZoom()
Dies ist hilfreich, wenn Sie Text für das Zoomverhältnis neben einem Schieberegler anzeigen lassen möchten.
Sehen Sie sich einfach das ZoomState
LiveData
an, um beide zu aktualisieren, ohne dass
Conversion.
Die von beiden APIs zurückgegebene ListenableFuture
bietet die Option für Anwendungen
wird benachrichtigt, wenn eine wiederkehrende Anfrage mit dem angegebenen Zoomwert
abgeschlossen. Wenn Sie während des vorherigen Vorgangs einen neuen Zoom-Wert festlegen,
wird noch ausgeführt, schlägt der ListenableFuture
des vorherigen Zoomvorgangs fehl.
sofort.
Fackel
CameraControl.enableTorch(boolean)
die Taschenlampe aktiviert oder deaktiviert.
CameraInfo.getTorchState()
kann verwendet werden, um den aktuellen Taschenlampenstatus abzufragen. Sie können den zurückgegebenen Wert
von
CameraInfo.hasFlashUnit()
um festzustellen, ob eine Taschenlampe verfügbar ist. Wenn nicht, rufen Sie
CameraControl.enableTorch(boolean)
führt dazu, dass die zurückgegebene ListenableFuture
in
sofort mit dem Fehlschlagen des Ergebnisses abgeschlossen und den Taschenlampenstatus auf
TorchState.OFF
Wenn die Taschenlampe aktiviert ist, bleibt sie bei Foto- und Videoaufnahmen eingeschaltet.
unabhängig von der flashMode-Einstellung. Die
flashMode
Zoll
ImageCapture
funktioniert nur, wenn die Taschenlampe deaktiviert ist.
Fokus und Belichtung
CameraControl.startFocusAndMetering()
löst die Autofokus- und Belichtungsmessung aus, indem AF/AE/AWB-Messbereiche festgelegt werden
basierend auf der gegebenen FocusMeteringAction. Dies wird häufig verwendet, um die Schaltfläche
in vielen Kamera-Apps verwenden.
Messpunkt
Erstellen Sie zunächst eine
MeteringPoint
verwendet
MeteringPointFactory.createPoint(float x, float y, float
size)
Ein MeteringPoint
steht für einen einzelnen Punkt auf der Kamera
Surface
Sie werden in einer normalisierten Form gespeichert.
sodass sie leicht in Sensorkoordinaten konvertiert werden können,
AF/AE/AWB-Regionen.
Die Größe von MeteringPoint
liegt zwischen 0 und 1, wobei die Standardgröße ist:
0.15f. Beim Aufrufen von MeteringPointFactory.createPoint(float x, float y, float
size)
erstellt CameraX einen rechteckigen Bereich, der bei (x, y)
für das angegebene Objekt zentriert ist.
size
Der folgende Code zeigt, wie ein MeteringPoint
erstellt wird:
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)
startFocusAndMetering und FocusMeteringAction
Zum Aufrufen
startFocusAndMetering()
,
Anwendungen müssen eine
FocusMeteringAction
die aus mindestens einem MeteringPoints
mit optionalem Metering-Modus besteht
Kombinationen aus
FLAG_AF
FLAG_AE
,
FLAG_AWB
. Die
folgen Sie dem Code, um diese Verwendung zu demonstrieren:
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)
Wie der vorherige Code zeigt,
startFocusAndMetering()
nimmt eine FocusMeteringAction
bestehend aus einer MeteringPoint
für AF/AE/AWB.
nur für AF und AE verfügbar.
KameraX wandelt sie intern in Camera2 um.
MeteringRectangles
und legt die entsprechenden
CONTROL_AF_REGIONS
/
CONTROL_AE_REGIONS
/
CONTROL_AWB_REGIONS
.
-Parameter zur Erfassungsanfrage hinzu.
Da nicht jedes Gerät AF/AE/AWB und mehrere Regionen unterstützt, führt CameraX
die FocusMeteringAction
nach bestem Wissen und Gewissen. CameraX verwendet die maximale Anzahl
der unterstützten Messpunkte in der Reihenfolge, in der die Punkte hinzugefügt wurden. Alle
Messpunkte, die nach der maximalen Anzahl hinzugefügt werden, werden ignoriert. Wenn zum Beispiel ein
Bei FocusMeteringAction
sind 3 MeteringPoints auf einer Plattform vorhanden, die
nur 2 auswählen, werden nur die ersten beiden MeteringPoints verwendet. Der letzte MeteringPoint
ist
wird von CameraX ignoriert.
Belichtungskorrektur
Mit der Belichtungskorrektur können Anwendungen die Belichtung optimieren -Werte (LW) über das Ausgabeergebnis für die automatische Belichtung (AE) hinaus. Belichtungskorrektur werden folgendermaßen kombiniert, um die erforderliche Exposition für Aktuelle Bildbedingungen:
Exposure = ExposureCompensationIndex * ExposureCompensationStep
CameraX bietet die
Camera.CameraControl.setExposureCompensationIndex()
zum Festlegen der Belichtungskorrektur als Indexwert.
Positive Indexwerte machen das Bild heller, während negative Werte das Bild dimmen
Bild. Anwendungen können den unterstützten Bereich abfragen, indem sie
CameraInfo.ExposureState.exposureCompensationRange()
die im nächsten Abschnitt beschrieben werden. Wenn der Wert unterstützt wird, wird der zurückgegebene Wert
ListenableFuture
wird abgeschlossen, wenn der Wert im
Anforderung erfassen; wenn der angegebene Index außerhalb des unterstützten Bereichs liegt,
setExposureCompensationIndex()
bewirkt, dass ListenableFuture
sofort mit einem fehlgeschlagenen Ergebnis abschließen.
CameraX behält nur die neuesten ausstehenden setExposureCompensationIndex()
bei
und die Funktion mehrmals vor der vorherigen Anfrage aufrufen.
ausgeführt wird, führt zu deren Abbruch.
Mit dem folgenden Snippet wird ein Belichtungskompensationsindex festgelegt und ein Callback für die Ausführung der Anforderungsänderung:
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()
ruft den aktuellenExposureState
einschließlich:- Die Unterstützung für die Belichtungskorrektur.
- Der aktuelle Belichtungskompensationsindex.
- Der Belichtungskompensationsindexbereich.
- Der Belichtungskorrekturschritt, der als Belichtungskorrekturwert verwendet wird Berechnung.
Mit dem folgenden Code werden beispielsweise die Einstellungen für einen Kontakt
SeekBar
mit der aktuellen ExposureState
Werte:
Kotlin
val exposureState = camera.cameraInfo.exposureState binding.seekBar.apply { isEnabled = exposureState.isExposureCompensationSupported max = exposureState.exposureCompensationRange.upper min = exposureState.exposureCompensationRange.lower progress = exposureState.exposureCompensationIndex }
Weitere Informationen
Weitere Informationen zu CameraX finden Sie in den folgenden Ressourcen.
Codelab
Codebeispiel
Entwickler-Community
Diskussionsgruppe zu Android CameraX