Android Pictures Are Rotated 90 Degrees When I Upload Them

This topic showcases how to set up CameraX employ cases inside your app to go images with the correct rotation information, whether it's from the ImageAnalysis or the ImageCapture use case. And so:

  • The ImageAnalysis use example'southward Analyzer should receive frames with the correct rotation.
  • The ImageCapture use case should take pictures with the right rotation.

Terminology

This topic uses the following terminology, so understanding what each term means is important:

Display orientation
This refers to which side of the device is in the upward position, and can be one of four values: portrait, mural, contrary portrait, or reverse landscape.
Display rotation
This is the value returned by Display.getRotation(), and represents the degrees past which the device is rotated counter-clockwise from its natural orientation.
Target rotation
This represents the number of degrees through which to rotate the device clockwise to reach its natural orientation.

How to determine the target rotation

The post-obit examples show how to determine the target rotation for a device based on its natural orientation.

Example 1: Portrait natural orientation

Device instance: Pixel 3 XL

Natural orientation = Portrait
Electric current orientation = Portrait

Display rotation = 0
Target rotation = 0

Natural orientation = Portrait
Current orientation = Landscape

Display rotation = ninety
Target rotation = xc

Example 2: Landscape natural orientation

Device case: Pixel C

Natural orientation = Landscape
Electric current orientation = Mural

Display rotation = 0
Target rotation = 0

Natural orientation = Landscape
Electric current orientation = Portrait

Brandish rotation = 270
Target rotation = 270

Paradigm rotation

Which end is upwards? The sensor orientation is divers in Android as a constant value, which represents the degrees (0, 90, 180, 270) the sensor is rotated from the top of the device when the device is in a natural position. For all the cases in the diagrams, the epitome rotation describes how the data should be rotated clockwise to appear upright.

The following examples show what the image rotation should exist depending on the photographic camera sensor orientation. They too assume the target rotation is set to the display rotation.

Case 1: Sensor rotated 90 degrees

Device instance: Pixel 3 Twoscore

Display rotation = 0
Display orientation = Portrait
Image rotation = 90

Brandish rotation = 90
Brandish orientation = Landscape
Paradigm rotation = 0

Example ii: Sensor rotated 270 degrees

Device instance: Nexus 5X

Display rotation = 0
Display orientation = Portrait
Image rotation = 270

Brandish rotation = 90
Brandish orientation = Landscape
Image rotation = 180

Example 3: Sensor rotated 0 degrees

Device example: Pixel C (Tablet)

Display rotation = 0
Display orientation = Landscape
Paradigm rotation = 0

Display rotation = 270
Brandish orientation = Portrait
Image rotation = 90

Computing an epitome'south rotation

ImageAnalysis

ImageAnalysis'due south Analyzer receives images from the camera in the form of ImageProxysouth. Each paradigm contains rotation information, which is attainable via:

val rotation = imageProxy.imageInfo.rotationDegrees        

This value represents the degrees by which the prototype needs to be rotated clockwise to lucifer ImageAnalysis's target rotation. In the context of an Android app, ImageAnalysis'southward target rotation would typically lucifer the screen's orientation.

ImageCapture

A callback is attached to an ImageCapture example to point when a capture upshot is ready. The result can be either the captured paradigm or an error.

When taking a picture, the provided callback can be of one of the following types:

  • OnImageCapturedCallback: Receives an image with in-memory admission in the form of an ImageProxy.
  • OnImageSavedCallback: Invoked when the captured image has been successfully stored in the location specified by ImageCapture.OutputFileOptions. The options can specify a File, an OutputStream, or a location in MediaStore.

The rotation of the captured image, regardless of its format (ImageProxy, File, OutputStream, MediaStore Uri) represents the rotation degrees past which the captured paradigm needs to be rotated clockwise to match ImageCapture's target rotation, which once more, in the context of an Android app, would typically lucifer the screen's orientation.

Retrieving the captured paradigm'southward rotation tin can be washed in 1 of the post-obit ways:

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        

Verify an epitome's rotation

The ImageAnalysis and ImageCapture utilise cases receive ImageProxys from the photographic camera after a successful capture asking. An ImageProxy wraps an epitome and information about it, including its rotation. This rotation information represents the degrees by which the image has to be rotated to match the utilise case'due south target rotation.

An image's rotation verification flow

ImageCapture/ImageAnalysis target rotation guidelines

Since many devices don't rotate to reverse portrait or reverse landscape by default, some Android apps don't support these orientations. Whether an app supports it or not changes the fashion the use cases' target rotation can be updated.

Below are 2 tables defining how to keep the use cases' target rotation in sync with the display rotation. The first shows how to do and then while supporting all four orientations; the second only handles the orientations the device rotates to past default.

To choose which guidelines to follow in your app:

  1. Verify whether your app's camera Action has a locked orientation, an unlocked orientation, or if it overrides orientation configuration changes.

  2. Decide whether your app'south camera Activity should handle all iv device orientations (portrait, reverse portrait, landscape, and reverse landscape), or if it should only handle orientations the device it'southward running on supports past default.

Support all four orientations

This table mentions certain guidelines to follow for cases where the device doesn't rotate to contrary portrait. The aforementioned tin be applied to devices that don't rotate to opposite mural.

Scenario Guidelines Unmarried-window mode Multi-window split-screen mode
Unlocked orientation Prepare up the use cases every fourth dimension the Activity is created, such as in the Activity'south onCreate() callback.
Utilise OrientationEventListener's onOrientationChanged(). Inside the callback, update the target rotation of the employ cases. This handles cases where the system doesn't recreate the Action fifty-fifty later on an orientation alter, such every bit when the device is rotated 180 degrees. Also handles when the display is in a reverse portrait orientation and the device doesn't rotate to opposite portrait by default. Likewise handles cases where the Activity isn't recreated when the device rotates (90 degrees, for example). This happens on small class factor devices when the app takes up half the screen, and on larger devices when the app takes upward two thirds of the screen.
Optional: Gear up the Activity'southward screenOrientation holding to fullSensor in the AndroidManifest file. This allows for the UI to be upright when the device is in reverse portrait, and allows for the Action to exist recreated past the arrangement whenever the device is rotated by xc degrees. Has no effect on devices that don't rotate to opposite portrait by default. Multi-window fashion isn't supported while the display is in a contrary portrait orientation.
Locked orientation Set upwards the use cases just one time, when the Action is first created, such as in the Action's onCreate() callback.
Use OrientationEventListener's onOrientationChanged(). Within the callback, update the target rotation of the use cases. Likewise handles cases where the Activity isn't recreated when the device rotates (90 degrees, for case). This happens on small form gene devices when the app takes up one-half the screen, and on larger devices when the app takes up two thirds of the screen.
Orientation configChanges overridden Gear up the use cases just once, when the Activity is first created, such as in the Activity'south onCreate() callback.
Employ OrientationEventListener'southward onOrientationChanged(). Inside the callback, update the target rotation of the utilize cases. Also handles cases where the Action isn't recreated when the device rotates (90 degrees, for example). This happens on small grade factor devices when the app takes up half the screen, and on larger devices when the app takes up two thirds of the screen.
Optional: Set the Activity's screenOrientation property to fullSensor in the AndroidManifest file. Allows for the UI to be upright when the device is in reverse portrait. Has no effect on devices that don't rotate to reverse portrait by default. Multi-window manner isn't supported while the display is in a opposite portrait orientation.

Back up just device-supported orientations

Support only orientations the device supports past default (which may or may not include reverse portrait/reverse mural).

Scenario Guidelines Multi-window split-screen mode
Unlocked orientation Fix the employ cases every time the Activity is created, such as in the Activeness'due south onCreate() callback.
Use DisplayListener's onDisplayChanged(). Inside the callback, update the target rotation of the apply cases, such equally when the device is rotated 180 degrees. Too handles cases where the Activity isn't recreated when the device rotates (90 degrees, for example). This happens on small form factor devices when the app takes up one-half the screen, and on larger devices when the app takes up 2 thirds of the screen.
Locked orientation Prepare upwards the employ cases just once, when the Activity is first created, such as in the Activity's onCreate() callback.
Use OrientationEventListener'due south onOrientationChanged(). Inside the callback, update the target rotation of the use cases. Also handles cases where the Activity isn't recreated when the device rotates (90 degrees, for instance). This happens on pocket-size form gene devices when the app takes up half the screen, and on larger devices when the app takes up two thirds of the screen.
Orientation configChanges overridden Gear up upwards the utilize cases only once, when the Activity is outset created, such equally in the Activeness's onCreate() callback.
Use DisplayListener's onDisplayChanged(). Within the callback, update the target rotation of the use cases, such as when the device is rotated 180 degrees. Also handles cases where the Activity isn't recreated when the device rotates (90 degrees, for case). This happens on small form factor devices when the app takes up one-half the screen, and on larger devices when the app takes up two thirds of the screen.

Unlocked orientation

An Activity has an unlocked orientation when its brandish orientation (such as portrait or landscape) matches the device'southward physical orientation, with the exception of contrary portrait/landscape, which some devices don't support by default. To force the device to rotate to all 4 orientations, prepare the Activeness'southward screenOrientation property to fullSensor.

In multi-window mode, a device that doesn't support reverse portrait/landscape by default won't rotate to reverse portrait/mural, fifty-fifty when its screenOrientation property is ready to fullSensor.

<!-- The Activity has an unlocked orientation, only might non rotate to reverse portrait/mural in single-window mode if the device doesn't support it by default. --> <action android:name=".UnlockedOrientationActivity" />  <!-- The Action has an unlocked orientation, and will rotate to all iv orientations in single-window style. --> <activity    android:name=".UnlockedOrientationActivity"    android:screenOrientation="fullSensor" />        

Locked orientation

A display has a locked orientation when it stays in the same brandish orientation (such as portrait or mural) regardless of the physical orientation of the device. This tin be done by specifying an Activity's screenOrientation property inside its declaration in the AndroidManifest.xml file.

When the display has a locked orientation, the system doesn't destroy and recreate the Activity as the device is rotated.

<!-- The Activity keeps a portrait orientation even as the device rotates. --> <activity    android:name=".LockedOrientationActivity"    android:screenOrientation="portrait" />        

Orientation configuration changes overridden

When an Activity overrides orientation configuration changes, the arrangement doesn't destroy and recreate it when the device'southward physical orientation changes. The system updates the UI though to match the device'due south physical orientation.

<!-- The Activity's UI might non rotate in opposite portrait/landscape if the device doesn't support it past default. --> <action    android:name=".OrientationConfigChangesOverriddenActivity"    android:configChanges="orientation|screenSize" />  <!-- The Action's UI volition rotate to all 4 orientations in single-window mode. --> <activity    android:name=".OrientationConfigChangesOverriddenActivity"    android:configChanges="orientation|screenSize"    android:screenOrientation="fullSensor" />        

Camera use cases setup

In the scenarios described in a higher place, the camera use cases tin can be set up when the Activity is beginning created.

In the case of an Activeness with an unlocked orientation, this setup is done every time the device is rotated, equally the organization destroys and recreates the Activity on orientation changes. This results in the utilise cases setting their target rotation to lucifer the brandish'south orientation by default each time.

In the case of an Activity with a locked orientation or one that overrides orientation configuration changes, this setup is done once, when the Activity is outset created.

grade CameraActivity : AppCompatActivity() {    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)         val cameraProcessFuture = ProcessCameraProvider.getInstance(this)        cameraProcessFuture.addListener(Runnable {           val cameraProvider = cameraProcessFuture.get()            // Past 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 setup

Using an OrientationEventListener allows you to continuously update the target rotation of the camera use cases equally the device's orientation changes.

class CameraActivity : AppCompatActivity() {      individual val orientationEventListener by lazy {         object : OrientationEventListener(this) {             override fun onOrientationChanged(orientation: Int) {                 if (orientation == UNKNOWN_ORIENTATION) {                     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 setup

Using a DisplayListener allows y'all to update the target rotation of the camera utilise cases in certain situations, for case when the system doesn't destroy and recreate the Activity subsequently the device rotates by 180 degrees.

class CameraActivity : AppCompatActivity() {      private val displayListener = object : DisplayManager.DisplayListener {         override fun onDisplayChanged(displayId: Int) {             if (rootView.brandish.displayId == displayId) {                 val rotation = rootView.brandish.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)     } }        

cramerconalothe.blogspot.com

Source: https://developer.android.com/training/camerax/orientation-rotation

0 Response to "Android Pictures Are Rotated 90 Degrees When I Upload Them"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel