CameraX设备锁定方向时拍摄图片旋转问题求解
解决CameraX锁定设备方向后拍摄图片旋转的问题
问题根源
系统方向锁定后,Activity的配置方向不再随设备旋转变化,但相机传感器的物理方向是固定的,此时ImageCapture默认的方向配置会与实际拍摄场景不匹配,导致最终保存的图片出现旋转偏移。
解决方案
通过手动计算并设置ImageCapture的目标旋转角度,让CameraX根据设备物理旋转和相机传感器方向自动调整图片方向,同时正确写入Exif方向信息,确保图片显示正常。
1. 实现旋转角度计算方法
添加方法获取设备当前物理旋转与相机传感器方向的匹配角度:
private fun calculateCaptureOrientation(): Int { val deviceRotation = windowManager.defaultDisplay.rotation val sensorOrientation = camera?.cameraInfo?.sensorOrientation ?: 0 return when (deviceRotation) { Surface.ROTATION_0 -> sensorOrientation Surface.ROTATION_90 -> (sensorOrientation + 270) % 360 Surface.ROTATION_180 -> (sensorOrientation + 180) % 360 Surface.ROTATION_270 -> (sensorOrientation + 90) % 360 else -> sensorOrientation } }
2. 配置ImageCapture的目标旋转
修改bindPreview()中的ImageCapture构建代码,加入目标旋转设置:
imageCapture = ImageCapture.Builder() .setFlashMode(flashMode) .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY) .setTargetRotation(calculateCaptureOrientation()) // 新增该行 .build()
3. 拍摄前更新旋转角度(可选)
如果设备在锁定方向后仍有旋转操作,建议在拍摄按钮点击事件中重新计算并设置旋转角度,确保每次拍摄都使用最新的方向配置:
// 拍摄按钮点击逻辑 binding.captureBtn.setOnClickListener { imageCapture.targetRotation = calculateCaptureOrientation() // 执行拍摄操作 val outputFile = createTempFile(System.currentTimeMillis().toString(), ".jpg") val outputOptions = ImageCapture.OutputFileOptions.Builder(outputFile).build() imageCapture.takePicture( outputOptions, cameraExecutor, object : ImageCapture.OnImageSavedCallback { override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) { // 图片保存成功后的处理 } override fun onError(exception: ImageCaptureException) { // 错误处理 } } ) }
原理说明
setTargetRotation()会让CameraX根据指定的旋转角度调整拍摄的图片,同时自动在图片的Exif元数据中写入正确的方向信息,确保图片在任何场景下(包括上传服务器后)都能正确显示方向,和WhatsApp等应用的处理逻辑一致。
内容的提问来源于stack exchange,提问作者james04
相关产品推荐
相关产品推荐

