Rotationen der CameraX-Anwendungsfälle

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
Aktuelle Ausrichtung = Hochformat

Displaydrehung = 0
Zielrotation = 0

Natürliche Ausrichtung = Hochformat
Aktuelle Ausrichtung = Querformat

Anzeigenrotation = 90
Zielrotation = 90

Beispiel 2: Natürliche Ausrichtung im Querformat

Gerätebeispiel: Pixel C

Natürliche Ausrichtung = Querformat
Aktuelle Ausrichtung = Querformat

Displaydrehung = 0
Zielrotation = 0

Natürliche Ausrichtung = Querformat
Aktuelle Ausrichtung = Hochformat

Anzeigenrotation = 270
Zielrotation = 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
Displayausrichtung = Hochformat
Bilddrehung = 90

Anzeigenrotation = 90
Displayausrichtung = Querformat
Bilddrehung = 0

Beispiel 2: Sensor um 270 Grad gedreht

Gerätebeispiel: Nexus 5X

Displaydrehung = 0
Displayausrichtung = Hochformat
Bilddrehung = 270

Anzeigenrotation = 90
Displayausrichtung = Querformat
Bilddrehung = 180

Beispiel 3: Sensor um 0 Grad gedreht

Gerätebeispiel: Pixel C (Tablet)

Displaydrehung = 0
Displayausrichtung = Querformat
Bilddrehung = 0

Anzeigenrotation = 270
Displayausrichtung = Hochformat
Bilddrehung = 90

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 der ImageProxy.
  • OnImageSavedCallback:Wird aufgerufen, wenn das aufgenommene Bild an dem durch das Feld ImageCapture.OutputFileOptions. Mit den Optionen kann ein File, ein OutputStream oder ein Ort in MediaStore.

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 ImageProxys 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.

Ablauf zur Überprüfung der Rotation eines Bildes

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:

  1. Prüfe, ob die Kamera „Activity“ deiner App nicht korrekt ausgerichtet ist, die Ausrichtung entsperrt oder die Konfigurationsänderungen überschrieben werden.

  2. 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 Activitys 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)
    }
}