Android 具有固定方向的CameraX图像旋转

Android 具有固定方向的CameraX图像旋转,android,android-camerax,Android,Android Camerax,我在我的应用程序中添加了cameraX,如本文所述。我面临的唯一问题是图像旋转。在应用程序清单文件中,我将此设置用于相机活动android:screenOrientation=“肖像”。我的目标是使此活动始终处于纵向模式,而捕获的图像应具有真正的旋转 我怎样才能做到这一点?活动固定时,cameraX是否可以检测不同的旋转 这是我在照相机活动中的代码 private lateinit var cameraProviderFuture: ListenableFuture<ProcessCame

我在我的应用程序中添加了cameraX,如本文所述。我面临的唯一问题是图像旋转。在应用程序清单文件中,我将此设置用于相机活动
android:screenOrientation=“肖像”
。我的目标是使此活动始终处于纵向模式,而捕获的图像应具有真正的旋转

我怎样才能做到这一点?活动固定时,cameraX是否可以检测不同的旋转

这是我在照相机活动中的代码

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()
            })
        }
    })
}
private lateinit var cameraProviderFuture:ListenableFuture
私有lateinit var imageCapture:imageCapture
private val executor=Executors.newSingleThreadExecutor()
私人var摄像机:摄像机?=无效的
...
重写创建时的乐趣(savedInstanceState:Bundle?)
{
...
cameraProviderFuture=ProcessCameraProvider.getInstance(此)
preview\u view.post(
{
startCamera()
})
}
...
乐趣之星
{
preview=preview.Builder().apply{
SetTargetSpectratio(AspectRatio.RATIO_16_9)
setTargetRotation(预览视图、显示、旋转)
}.build()
imageCapture=imageCapture.Builder().apply{
setCaptureMode(ImageCapture.CAPTURE\u模式\u最小化延迟)
}.build()
val cameraSelector=cameraSelector.Builder().requirensFacing(cameraSelector.LENS_-FACING_-BACK).build()
cameraProviderFuture.addListener(可运行{
val cameraProvider=cameraProviderFuture.get()
cameraProvider.unbindAll()
camera=cameraProvider.bindToLifecycle(此、cameraSelector、预览、图像捕获)
preview.setSurfaceProvider(preview\u view.createSurfaceProvider(camera!!.cameraInfo))
},ContextCompat.getMainExecutor(此))
}
...
趣味照
{
val file=createFile(getOutputDirectory(),文件名,照片扩展名)
val outputFileOptions=ImageCapture.outputFileOptions.Builder(file.build())
imageCapture.takePicture(outputFileOptions,executor,对象:imageCapture.OnImageSavedCallback
{
覆盖已保存的图像(outputFileResults:ImageCapture.outputFileResults)
{
val my_file_item=MyFileItem.createFromFile(文件)
图像捕获(我的文件项目)
}
重写错误(异常:ImageCaptureException)
{
val msg=“照片捕获失败:${exception.message}”
preview\u view.post({
Toast.makeText(this@ActPhotoCapture2,msg,Toast.LENGTH\u LONG).show()
})
}
})
}

如果您的方向被锁定,您可能可以使用方向侦听器来侦听设备方向的更改,并且每次调用其
onOrientationChanged
回调时,您都会为图像捕获用例设置目标旋转

val orientationEventListener = object : OrientationEventListener(context) {
    override fun onOrientationChanged(orientation: Int) {
        imageCapture.targetRotation = view.display.rotation
    }
}
用于获取旋转的视图可以是任何视图,例如位于fragment中的根视图,或者只是PreviewView。您还可以在
onResume
onPause
中启用/禁用此侦听器


ps:您设置用例的方式可能会导致问题。在相机启动之前,不应该初始化用例。您应该在这一行之后构建用例
val cameraProvider=cameraProviderFuture.get()

Husayn感谢您的回答,我已经实现了类似的解决方案,在调用takePicture之前设置imageCapture rotation,我将使用您关于初始化字段的建议。