Reputation: 811
I added cameraX in my app as it described in this tutorial. The only problem i faced is image rotation. In app manifest file I use this settings for camera activity android:screenOrientation="portrait"
. My goal is to make this activity always in portrait mode, while captured images should have real rotation.
How can i achieve this? Is it possible for cameraX to detect different rotation while activity has fixed?
This is my code in camera activity
private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>
private lateinit var imageCapture: ImageCapture
private val executor = Executors.newSingleThreadExecutor()
private var camera: Camera? = null
...
override fun onCreate(savedInstanceState: Bundle?)
{
...
cameraProviderFuture = ProcessCameraProvider.getInstance(this)
preview_view.post(
{
startCamera()
})
}
...
fun startCamera()
{
preview = Preview.Builder().apply {
setTargetAspectRatio(AspectRatio.RATIO_16_9)
setTargetRotation(preview_view.display.rotation)
}.build()
imageCapture = ImageCapture.Builder().apply {
setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
}.build()
val cameraSelector = CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build()
cameraProviderFuture.addListener(Runnable {
val cameraProvider = cameraProviderFuture.get()
cameraProvider.unbindAll()
camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture)
preview.setSurfaceProvider(preview_view.createSurfaceProvider(camera!!.cameraInfo))
}, ContextCompat.getMainExecutor(this))
}
...
fun takePicture()
{
val file = createFile(getOutputDirectory(), FILENAME, PHOTO_EXTENSION)
val outputFileOptions = ImageCapture.OutputFileOptions.Builder(file).build()
imageCapture.takePicture(outputFileOptions, executor, object : ImageCapture.OnImageSavedCallback
{
override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults)
{
val my_file_item = MyFileItem.createFromFile(file)
imageCaptured(my_file_item)
}
override fun onError(exception: ImageCaptureException)
{
val msg = "Photo capture failed: ${exception.message}"
preview_view.post({
Toast.makeText(this@ActPhotoCapture2, msg, Toast.LENGTH_LONG).show()
})
}
})
}
Upvotes: 1
Views: 4227
Reputation: 4570
If your orientation is locked, you can probably use an orientation listener to listen for changes in the device's orientation, and each time its onOrientationChanged
callback is invoked, you'd set the target rotation for the image capture use case.
val orientationEventListener = object : OrientationEventListener(context) {
override fun onOrientationChanged(orientation: Int) {
imageCapture.targetRotation = view.display.rotation
}
}
The view you use to get the rotation can be any view, for example the root view if you're in fragment, or just the PreviewView. You can also enable/disable this listener in onResume
and onPause
.
ps: The way you're setting up your use cases can cause issues. The use cases shouldn't be initialized before the camera is started. You should build the use cases after this line val cameraProvider = cameraProviderFuture.get()
.
Upvotes: 6