固定 sreenOrientation 的 CameraX 图像旋转
CameraX image rotation with fixed sreenOrientation
我按照 tutorial 中的说明在我的应用中添加了 cameraX。我面临的唯一问题是图像旋转。在应用程序清单文件中,我将此设置用于相机 activity android:screenOrientation="portrait"
。我的目标是让这个 activity 始终处于纵向模式,而捕获的图像应该有真正的旋转。
我怎样才能做到这一点? activity 固定后,cameraX 是否可以检测到不同的旋转?
这是我在相机中的代码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()
})
}
})
}
如果您的方向被锁定,您可以使用方向侦听器来侦听设备方向的变化,并且每次调用其 onOrientationChanged
回调时,您需要为图像设置目标旋转捕获用例。
val orientationEventListener = object : OrientationEventListener(context) {
override fun onOrientationChanged(orientation: Int) {
imageCapture.targetRotation = view.display.rotation
}
}
您用来获取旋转的视图可以是任何视图,例如,如果您在片段中,则为根视图,或者只是 PreviewView。您还可以在 onResume
和 onPause
.
中 enable/disable 此侦听器
ps:您设置用例的方式可能会导致问题。在相机启动之前不应初始化用例。您应该在此行 val cameraProvider = cameraProviderFuture.get()
.
之后构建用例
我按照 tutorial 中的说明在我的应用中添加了 cameraX。我面临的唯一问题是图像旋转。在应用程序清单文件中,我将此设置用于相机 activity android:screenOrientation="portrait"
。我的目标是让这个 activity 始终处于纵向模式,而捕获的图像应该有真正的旋转。
我怎样才能做到这一点? activity 固定后,cameraX 是否可以检测到不同的旋转?
这是我在相机中的代码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()
})
}
})
}
如果您的方向被锁定,您可以使用方向侦听器来侦听设备方向的变化,并且每次调用其 onOrientationChanged
回调时,您需要为图像设置目标旋转捕获用例。
val orientationEventListener = object : OrientationEventListener(context) {
override fun onOrientationChanged(orientation: Int) {
imageCapture.targetRotation = view.display.rotation
}
}
您用来获取旋转的视图可以是任何视图,例如,如果您在片段中,则为根视图,或者只是 PreviewView。您还可以在 onResume
和 onPause
.
ps:您设置用例的方式可能会导致问题。在相机启动之前不应初始化用例。您应该在此行 val cameraProvider = cameraProviderFuture.get()
.