In diesem Thema erfahren Sie, wie Sie CameraX-Anwendungsfälle in Ihrer App einrichten,
mit den richtigen Rotationsinformationen, egal ob aus der
ImageAnalysis
oder ImageCapture
. Also:
Analyzer
des Anwendungsfalls „ImageAnalysis
“ sollte Frames mit der richtige Drehung.- Mit dem Anwendungsfall „
ImageCapture
“ sollten Bilder mit der richtigen Drehung aufgenommen werden.
Terminologie
In diesem Thema wird die folgende Terminologie verwendet. Sie müssen also verstehen, was die einzelnen Begriffe bedeuten. ist wichtig:
- Displayausrichtung
- Damit wird angegeben, welche Seite des Geräts sich nach oben befindet. einen von vier Werten: Hochformat, Querformat, umgekehrt, Hochformat oder umgekehrt Landschaft.
- Displaydrehung
- Dies ist der von
Display.getRotation()
und stellt die Grad dar, um die das Gerät gegen den Uhrzeigersinn von natürliche Ausrichtung. - Zielrotation
- Die Gradzahl für die Drehung das Gerät im Uhrzeigersinn, bis es seine natürliche Ausrichtung erreicht.
So legen Sie die Zielrotation fest
Die folgenden Beispiele zeigen, wie die Zieldrehung eines Geräts bestimmt wird basierend auf seiner natürlichen Ausrichtung.
Beispiel 1: Natürliche Ausrichtung im Hochformat
Gerätebeispiel: Pixel 3 XL | |
---|---|
Natürliche Ausrichtung = Hochformat Displaydrehung = 0 |
|
Natürliche Ausrichtung = Hochformat Anzeigenrotation = 90 |
Beispiel 2: Natürliche Ausrichtung im Querformat
Gerätebeispiel: Pixel C | |
---|---|
Natürliche Ausrichtung = Querformat Displaydrehung = 0 |
|
Natürliche Ausrichtung = Querformat Anzeigenrotation = 270 |
Bilddrehung
Welches Ziel ist erreicht? Die Sensorausrichtung ist in Android als konstant -Wert, der den Grad (0, 90, 180, 270) angibt, von dem aus der Sensor gedreht wird an der Oberseite des Geräts, wenn es sich in einer natürlichen Position befindet. Für alle In den Diagrammen beschreibt die Bildrotation, wie die Daten im Uhrzeigersinn gedreht, bis sie aufrecht erscheint.
Die folgenden Beispiele zeigen, wie die Bilddrehung je nach Ausrichtung des Kamerasensors. Sie gehen auch davon aus, dass die Zielrotation Displaydrehung.
Beispiel 1: Sensor um 90 Grad gedreht
Gerätebeispiel: Pixel 3 XL | |
---|---|
Displaydrehung = 0 |
|
Anzeigenrotation = 90 |
Beispiel 2: Sensor um 270 Grad gedreht
Gerätebeispiel: Nexus 5X | |
---|---|
Displaydrehung = 0 |
|
Anzeigenrotation = 90 |
Beispiel 3: Sensor um 0 Grad gedreht
Gerätebeispiel: Pixel C (Tablet) | |
---|---|
Displaydrehung = 0 |
|
Anzeigenrotation = 270 |
Rotation eines Bildes berechnen
Bildanalyse
Analyzer
von ImageAnalysis
empfängt Bilder von der Kamera in Form von
ImageProxy
Sek. Jedes Bild enthält Rotationsinformationen, auf die
über:
val rotation = imageProxy.imageInfo.rotationDegrees
Dieser Wert gibt den Grad an, um den das Bild gedreht werden muss.
im Uhrzeigersinn, bis er der Zielrotation von ImageAnalysis
entspricht. Im Zusammenhang mit einer
Android-App entspricht die Zielrotation von ImageAnalysis
normalerweise der
Bildschirmausrichtung.
Bilderfassung
Ein Callback ist an eine ImageCapture
-Instanz angehängt, um zu signalisieren, wenn eine Erfassung
Ergebnis ist fertig. Das Ergebnis kann entweder das aufgenommene Bild oder ein Fehler sein.
Beim Aufnehmen eines Fotos kann der bereitgestellte Callback einer der folgenden sein: Typen:
OnImageCapturedCallback
: Erhält ein Bild mit speicherinternem Zugriff in derImageProxy
.OnImageSavedCallback
:Wird aufgerufen, wenn das aufgenommene Bild an dem durch das FeldImageCapture.OutputFileOptions
. Mit den Optionen kann einFile
, einOutputStream
oder ein Ort inMediaStore
.
Die Drehung des aufgenommenen Bildes unabhängig von seinem Format (ImageProxy
,
File
, OutputStream
, MediaStore Uri
) steht für die Drehung in
Das aufgenommene Bild muss im Uhrzeigersinn gedreht werden, um dem ImageCapture
-Wert zu entsprechen.
was auch hier im Kontext einer Android-App
Bildschirmausrichtung entspricht.
Sie haben folgende Möglichkeiten, die Rotation eines aufgenommenen Bildes abzurufen Möglichkeiten:
ImageProxy
val rotation = imageProxy.imageInfo.rotationDegrees
File
val exif = Exif.createFromFile(file) val rotation = exif.rotation
OutputStream
val byteArray = outputStream.toByteArray() val exif = Exif.createFromInputStream(ByteArrayInputStream(byteArray)) val rotation = exif.rotation
MediaStore uri
val inputStream = contentResolver.openInputStream(outputFileResults.savedUri) val exif = Exif.createFromInputStream(inputStream) val rotation = exif.rotation
Rotation eines Bildes prüfen
Die Anwendungsfälle ImageAnalysis
und ImageCapture
erhalten ImageProxy
s aus dem
nachdem die Aufnahmeanfrage erfolgreich war. Ein ImageProxy
umschließt ein Bild und
um Informationen darüber zu erhalten, einschließlich der Rotation. Diese Rotationsinformationen
stellt den Grad dar, um den das Bild gedreht werden muss, damit es der Verwendung entspricht
die Zielrotation des Falls festzulegen.
Richtlinien für die Zielrotation von ImageCapture/ImageAnalysis
Da sich viele Geräte nicht drehen, um das Hoch- oder Querformat umzukehren, Standardmäßig unterstützen einige Android-Apps diese Ausrichtungen nicht. Ob eine App unterstützt oder nicht ändert die Art und Weise, wie die Zielrotation der Anwendungsfälle aktualisiert.
Unten sehen Sie zwei Tabellen, in denen definiert ist, wie die Zielrotation der Anwendungsfälle synchron gehalten werden kann mit der Display-Drehung. Im ersten Beispiel wird gezeigt, wie das geht und gleichzeitig alle vier Ausrichtungen auswählen: im zweiten nur die Ausrichtungen, die das Gerät dreht, standardmäßig auf.
So wählen Sie die Richtlinien für Ihre App aus:
Prüfe, ob die Kamera „
Activity
“ deiner App nicht korrekt ausgerichtet ist, die Ausrichtung entsperrt oder die Konfigurationsänderungen überschrieben werden.Lege fest, ob deine App-Kamera
Activity
alle vier Geräte verarbeiten soll Ausrichtungen (Hochformat, umgekehrtes Hochformat, Querformat und umgekehrtes Querformat) oder nur die Ausrichtungen des Geräts unterstützt werden sollen, ist standardmäßig aktiviert.
Alle vier Ausrichtungen unterstützen
In dieser Tabelle sind bestimmte Richtlinien aufgeführt, die Sie beachten sollten, wenn das Gerät wird nicht in das Hochformat gedreht. Das Gleiche gilt für Geräte, nicht zum umgekehrten Querformat drehen.
Szenario | Richtlinien | Einzelfenstermodus | Mehrfenstermodus für geteilten Bildschirm |
---|---|---|---|
Ausrichtung ohne SIM-Lock |
Richten Sie die Anwendungsfälle alle
Zeitpunkt der Erstellung des Activity , z. B. im
onCreate() -Rückruf von Activity .
|
||
OrientationEventListener verwenden
onOrientationChanged()
Aktualisiere im Callback die Zielrotation der Anwendungsfälle. Das ist der Fall, wenn das System
Activity auch nach einer Änderung der Ausrichtung neu erstellen, z. B.
als wenn das Gerät um 180 Grad gedreht wird.
|
Wird auch behandelt, wenn das Display rückwärts wiedergegeben wird. Hochformat und das Gerät dreht sich nicht, um das Hochformat Standardeinstellung. |
Unterstützt auch Fälle, in denen Activity nicht
bei der Drehung des Geräts (z. B. um 90 Grad) neu erstellt wird. Dies geschieht am
Geräte mit kleinem Formfaktor, wenn die App die Hälfte des Bildschirms einnimmt, auf größeren
wenn die App zwei Drittel des Bildschirms einnimmt.
|
|
Optional: screenOrientation für Activity festlegen
Property zu fullSensor im AndroidManifest
-Datei.
|
Dadurch kann die Benutzeroberfläche aufrecht angezeigt werden, wenn das Gerät im Rückwärtsgang steht.
Hochformat und ermöglicht, dass Activity vom
wenn das Gerät um 90 Grad gedreht wird.
|
Dies hat keine Auswirkungen auf Geräte, die nicht um das Hochformat drehen. Standardeinstellung. Der Mehrfenstermodus wird nicht unterstützt, wenn sich das Display in einem Hochformat umgekehrt. | |
Gesperrte Ausrichtung |
Richten Sie die Anwendungsfälle nur einmal ein, wenn die
Activity wird zuerst erstellt, z. B. in der von Activity
onCreate() -Rückruf.
|
||
OrientationEventListener verwenden
onOrientationChanged()
Aktualisiere im Callback die Zielrotation der Anwendungsfälle mit Ausnahme der Vorschau.
|
Unterstützt auch Fälle, in denen Activity nicht
bei der Drehung des Geräts (z. B. um 90 Grad) neu erstellt wird. Dies geschieht am
Geräte mit kleinem Formfaktor, wenn die App die Hälfte des Bildschirms einnimmt, auf größeren
wenn die App zwei Drittel des Bildschirms einnimmt.
|
||
Konfigurationsänderungen für die Ausrichtung überschrieben |
Richten Sie die Anwendungsfälle nur einmal ein, wenn die
Activity wird zuerst erstellt, z. B. in der von Activity
onCreate() -Rückruf.
|
||
OrientationEventListener verwenden
onOrientationChanged()
Aktualisiere im Callback die Zielrotation der Anwendungsfälle.
|
Unterstützt auch Fälle, in denen Activity nicht
bei der Drehung des Geräts (z. B. um 90 Grad) neu erstellt wird. Dies geschieht am
Geräte mit kleinem Formfaktor, wenn die App die Hälfte des Bildschirms einnimmt, auf größeren
wenn die App zwei Drittel des Bildschirms einnimmt.
|
||
Optional: Lege für die Eigenschaft „screenOrientation“ der Aktivität den Wert „fullSensor“ fest. die AndroidManifest-Datei. | Ermöglicht es, die Benutzeroberfläche aufrecht zu halten, wenn sich das Gerät im umgekehrten Hochformat befindet. | Dies hat keine Auswirkungen auf Geräte, die nicht um das Hochformat drehen. Standardeinstellung. Der Mehrfenstermodus wird nicht unterstützt, wenn sich das Display in einem Hochformat umgekehrt. |
Nur von Geräten unterstützte Ausrichtungen unterstützen
Es werden nur Ausrichtungen unterstützt, die das Gerät standardmäßig unterstützt. Diese können Vertauschtes Hoch- und Querformat möglicherweise nicht enthalten).
Szenario | Richtlinien | Mehrfenstermodus für geteilten Bildschirm |
---|---|---|
Ausrichtung ohne SIM-Lock |
Richten Sie die Anwendungsfälle alle
Zeitpunkt der Erstellung des Activity , z. B. im
onCreate() -Rückruf von Activity .
|
|
DisplayListener verwenden
onDisplayChanged() Im Inneren der
die Zielrotation der Anwendungsfälle, wie z. B. wenn die
Gerät um 180 Grad gedreht ist.
|
Unterstützt auch Fälle, in denen Activity nicht
bei der Drehung des Geräts (z. B. um 90 Grad) neu erstellt wird. Dies geschieht am
Geräte mit kleinem Formfaktor, wenn die App die Hälfte des Bildschirms einnimmt, auf größeren
wenn die App zwei Drittel des Bildschirms einnimmt.
|
|
Gesperrte Ausrichtung |
Richten Sie die Anwendungsfälle nur einmal ein, wenn die
Activity wird zuerst erstellt, z. B. in der von Activity
onCreate() -Rückruf.
|
|
OrientationEventListener verwenden
onOrientationChanged()
Aktualisiere im Callback die Zielrotation der Anwendungsfälle.
|
Unterstützt auch Fälle, in denen Activity nicht
bei der Drehung des Geräts (z. B. um 90 Grad) neu erstellt wird. Dies geschieht am
Geräte mit kleinem Formfaktor, wenn die App die Hälfte des Bildschirms einnimmt, auf größeren
wenn die App zwei Drittel des Bildschirms einnimmt.
|
|
Konfigurationsänderungen für die Ausrichtung überschrieben |
Richten Sie die Anwendungsfälle nur einmal ein, wenn die
Activity wird zuerst erstellt, z. B. in der von Activity
onCreate() -Rückruf.
|
|
DisplayListener verwenden
onDisplayChanged() Im Inneren der
die Zielrotation der Anwendungsfälle, wie z. B. wenn die
Gerät um 180 Grad gedreht ist.
|
Unterstützt auch Fälle, in denen Activity nicht
bei der Drehung des Geräts (z. B. um 90 Grad) neu erstellt wird. Dies geschieht am
Geräte mit kleinem Formfaktor, wenn die App die Hälfte des Bildschirms einnimmt, auf größeren
wenn die App zwei Drittel des Bildschirms einnimmt.
|
Ausrichtung entsperrt
Ein Activity
hat eine entsperrte Ausrichtung, wenn seine Displayausrichtung
(z. B. Hoch- oder Querformat) der physischen Ausrichtung des Geräts entspricht, wobei
Ausgenommen ist das umgekehrte Hochformat/Querformat, das von einigen Geräten nicht unterstützt wird.
ist standardmäßig aktiviert. Um eine Drehung des Geräts in alle vier Ausrichtungen zu erzwingen, stellen Sie die Option
Die Property „screenOrientation
“ von Activity
wird auf „fullSensor
“ gesetzt.
Gerät, das im Mehrfenstermodus kein umgekehrtes Hoch- und Querformat unterstützt
wird standardmäßig nicht ins Hoch- oder Querformat gedreht, auch wenn
Das Attribut „screenOrientation
“ ist auf „fullSensor
“ festgelegt.
<!-- The Activity has an unlocked orientation, but might not rotate to reverse portrait/landscape in single-window mode if the device doesn't support it by default. --> <activity android:name=".UnlockedOrientationActivity" /> <!-- The Activity has an unlocked orientation, and will rotate to all four orientations in single-window mode. --> <activity android:name=".UnlockedOrientationActivity" android:screenOrientation="fullSensor" />
Ausrichtung gesperrt
Ein Display hat eine feste Ausrichtung, wenn es dieselbe Displayausrichtung behält
(z. B. Hoch- oder Querformat), unabhängig von der physischen Ausrichtung des
. Dazu kann screenOrientation
eines Activity
s angegeben werden.
innerhalb der zugehörigen Deklaration in der Datei AndroidManifest.xml
.
Wenn das Display eine fixierte Ausrichtung hat, zerstört das System nicht
erstellt das Activity
neu, während das Gerät gedreht wird.
<!-- The Activity keeps a portrait orientation even as the device rotates. --> <activity android:name=".LockedOrientationActivity" android:screenOrientation="portrait" />
Änderungen der Ausrichtungskonfiguration überschrieben
Wenn Activity
die Konfigurationsänderungen der Ausrichtung überschreibt,
nicht zerstört oder neu erstellt, wenn sich die physische Ausrichtung des Geräts ändert.
Das System aktualisiert die Benutzeroberfläche jedoch entsprechend der Geräteausrichtung.
<!-- The Activity's UI might not rotate in reverse portrait/landscape if the device doesn't support it by default. --> <activity android:name=".OrientationConfigChangesOverriddenActivity" android:configChanges="orientation|screenSize" /> <!-- The Activity's UI will rotate to all 4 orientations in single-window mode. --> <activity android:name=".OrientationConfigChangesOverriddenActivity" android:configChanges="orientation|screenSize" android:screenOrientation="fullSensor" />
Anwendungsfälle für Kameras einrichten
In den oben beschriebenen Szenarien können die Anwendungsfälle der Kamera eingerichtet werden, wenn die Kamera
Activity
wird zuerst erstellt.
Bei einem Activity
mit entsperrter Ausrichtung ist die Einrichtung abgeschlossen
jedes Mal, wenn das Gerät gedreht wird, während das System
Activity
bei Ausrichtungsänderungen. Das führt dazu, dass die Anwendungsfälle
Zieldrehung so, dass sie standardmäßig jedes Mal an die Ausrichtung des Bildschirms angepasst wird.
Im Fall eines Activity
mit einer gesperrten Ausrichtung oder einer, die die Ausrichtung überschreibt
die Konfiguration der Ausrichtung ändert, wird die Einrichtung einmal vorgenommen, wenn die Activity
erstellt wird.
class CameraActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val cameraProcessFuture = ProcessCameraProvider.getInstance(this) cameraProcessFuture.addListener(Runnable { val cameraProvider = cameraProcessFuture.get() // By default, the use cases set their target rotation to match the // display’s rotation. val preview = buildPreview() val imageAnalysis = buildImageAnalysis() val imageCapture = buildImageCapture() cameraProvider.bindToLifecycle( this, cameraSelector, preview, imageAnalysis, imageCapture) }, mainExecutor) } }
OrientationEventListener einrichten
Mit einem OrientationEventListener
können Sie das Ziel kontinuierlich aktualisieren
Drehung der Kamera, wenn sich die Ausrichtung des Geräts ändert.
class CameraActivity : AppCompatActivity() { private val orientationEventListener by lazy { object : OrientationEventListener(this) { override fun onOrientationChanged(orientation: Int) { if (orientation == ORIENTATION_UNKNOWN) { return } val rotation = when (orientation) { in 45 until 135 -> Surface.ROTATION_270 in 135 until 225 -> Surface.ROTATION_180 in 225 until 315 -> Surface.ROTATION_90 else -> Surface.ROTATION_0 } imageAnalysis.targetRotation = rotation imageCapture.targetRotation = rotation } } } override fun onStart() { super.onStart() orientationEventListener.enable() } override fun onStop() { super.onStop() orientationEventListener.disable() } }
DisplayListener-Einrichtung
Mit einem DisplayListener
kannst du die Zieldrehung der Kamera aktualisieren
Anwendungsfälle in bestimmten Situationen, z. B. wenn das System nicht
und erstellen Sie die Activity
neu, nachdem sich das Gerät um 180 Grad gedreht hat.
class CameraActivity : AppCompatActivity() { private val displayListener = object : DisplayManager.DisplayListener { override fun onDisplayChanged(displayId: Int) { if (rootView.display.displayId == displayId) { val rotation = rootView.display.rotation imageAnalysis.targetRotation = rotation imageCapture.targetRotation = rotation } } override fun onDisplayAdded(displayId: Int) { } override fun onDisplayRemoved(displayId: Int) { } } override fun onStart() { super.onStart() val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager displayManager.registerDisplayListener(displayListener, null) } override fun onStop() { super.onStop() val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager displayManager.unregisterDisplayListener(displayListener) } }