Android Studio中如何修复CameraSource相机预览方向倾斜问题
解决CameraSource相机预览竖直显示问题
问题根因
你使用的CameraSource默认输出横屏帧数据,未适配设备竖屏姿态,直接将未做旋转处理的帧转换为Bitmap显示就会出现横向倾斜的情况。
1. 调整CameraSource初始化配置
你需要在初始化时设置适配竖屏的预览尺寸,避免预览拉伸,修改setupCameraSource方法如下:
private fun setupCameraSource() { val displayMetrics = activity!!.resources.displayMetrics val screenWidth = displayMetrics.widthPixels val screenHeight = displayMetrics.heightPixels cameraSource = CameraSource.Builder(activity, cameraSourceCustomDetector) .setAutoFocusEnabled(true) .setRequestedFps(10F) .setFacing(CameraSource.CAMERA_FACING_BACK) // 相机传感器默认横置,预览尺寸传值需宽高倒置适配竖屏 .setRequestedPreviewSize(screenHeight, screenWidth) .build() }
2. 帧数据转换时添加Bitmap旋转逻辑
你在CustomDetector.detect方法中拿到的原始帧是横屏格式,需要先按当前设备姿态旋转后再传入UI显示,步骤如下:
第一步:添加Bitmap旋转工具方法
在colorDetector类中添加旋转方法:
private fun rotateBitmap(bitmap: Bitmap, rotationDegree: Int): Bitmap { val matrix = Matrix() matrix.postRotate(rotationDegree.toFloat()) val rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true) // 回收原始Bitmap避免内存泄漏 bitmap.recycle() return rotatedBitmap }
第二步:添加旋转角度计算方法
根据当前设备朝向和摄像头类型计算正确的旋转角度:
private fun getCorrectRotation(): Int { val display = activity?.windowManager?.defaultDisplay ?: return 90 val baseDegree = when (display.rotation) { Surface.ROTATION_0 -> 90 // 正常竖屏 Surface.ROTATION_90 -> 0 // 左侧横屏 Surface.ROTATION_180 -> 270 // 反向竖屏 Surface.ROTATION_270 -> 180 // 右侧横屏 else -> 90 } // 前置摄像头需要额外处理镜像翻转 return if (cameraSource?.cameraFacing == CameraSource.CAMERA_FACING_FRONT) { (360 - baseDegree) % 360 } else { baseDegree } }
第三步:修改detect方法中的Bitmap处理逻辑
转换为Bitmap后先旋转再传入UI方法:
@RequiresApi(Build.VERSION_CODES.O) override fun detect(frame: Frame?): SparseArray<Point>? { val byteBuffer: ByteBuffer = frame!!.grayscaleImageData val bytes: ByteArray = byteBuffer.array() val w = frame.metadata.width val h = frame.metadata.height val yuvimage = YuvImage(bytes, ImageFormat.NV21, w, h, null) val baos = ByteArrayOutputStream() yuvimage.compressToJpeg( Rect(0, 0, w, h), 100, baos ) val jpegArray = baos.toByteArray() var bitmap = BitmapFactory.decodeByteArray(jpegArray, 0, jpegArray.size) // 新增:旋转Bitmap到正确朝向 val rotationDegree = getCorrectRotation() bitmap = rotateBitmap(bitmap, rotationDegree) val finalBitmap = bitmap activity?.runOnUiThread { getEditedImg(finalBitmap, finalBitmap.width, finalBitmap.height, cameraPreview!!, editCameraPreview!!, activity!!) } return null }
额外优化建议
- 若应用固定为竖屏展示,可以直接固定旋转角度为90度,无需动态计算,减少性能消耗
- 官方
CameraSource已随Google Play Services Vision库停止维护,后续迭代建议迁移到ML Kit的相机扫描组件,适配更简便
内容的提问来源于stack exchange,提问作者Chris Marec
相关产品推荐
相关产品推荐

