You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部分设备Camera预览旋转90度问题求助(camera:^0.11.0+1)

部分设备Camera预览旋转90度的解决方案

问题背景

使用camera: ^0.11.0+1包时,仅部分设备出现Camera预览画面旋转90度的问题。调试日志显示正常与异常设备的方向计算一致:
D/CameraOrientationUtil(14552): getRelativeImageRotation: destRotationDegrees=0, sourceRotationDegrees=90, isOppositeFacing=true, result=90
预览画面横向显示、内容旋转90度,但拍摄后的照片方向正常;手动旋转视图会导致原本正常的设备出现预览旋转问题。

修复方案

1. 自定义预览旋转逻辑,替代默认buildPreview

通过Transform组件动态计算并应用预览旋转角度,避免依赖包的适配问题:

Expanded(
  child: Transform.rotate(
    angle: _calculatePreviewRotation() * pi / 180,
    child: _cameraController!.buildPreview(),
  ),
)

编写角度计算方法,结合相机传感器方向和设备当前方向:

double _calculatePreviewRotation() {
  final camera = _cameraController!.description;
  final deviceOrientation = MediaQuery.of(context).orientation;
  final sensorOrientation = camera.sensorOrientation;

  // 前置摄像头需要镜像处理旋转角度
  if (camera.lensDirection == CameraLensDirection.front) {
    switch (deviceOrientation) {
      case Orientation.portraitUp:
        return -sensorOrientation.toDouble();
      case Orientation.landscapeLeft:
        return -(sensorOrientation - 90).toDouble();
      case Orientation.portraitDown:
        return -(sensorOrientation - 180).toDouble();
      case Orientation.landscapeRight:
        return -(sensorOrientation - 270).toDouble();
    }
  } else {
    // 后置摄像头直接适配方向
    switch (deviceOrientation) {
      case Orientation.portraitUp:
        return sensorOrientation.toDouble();
      case Orientation.landscapeLeft:
        return (sensorOrientation - 90).toDouble();
      case Orientation.portraitDown:
        return (sensorOrientation - 180).toDouble();
      case Orientation.landscapeRight:
        return (sensorOrientation - 270).toDouble();
    }
  }
}

2. 监听设备方向变化,实时更新预览

添加设备方向监听,确保预览角度随设备旋转实时调整:

@override
void initState() {
  super.initState();
  WidgetsBinding.instance.addObserver(this);
}

@override
void dispose() {
  WidgetsBinding.instance.removeObserver(this);
  super.dispose();
}

@override
void didChangeMetrics() {
  super.didChangeMetrics();
  setState(() {}); // 触发重绘更新旋转角度
}

3. 显式指定相机初始化的格式组

初始化CameraController时,指定imageFormatGroup为设备支持的格式,避免部分设备的适配冲突:

_cameraController = CameraController(
  selectedCamera,
  ResolutionPreset.medium,
  imageFormatGroup: ImageFormatGroup.jpeg, // 根据设备调整,部分设备可用ImageFormatGroup.yuv420
);

原因分析

日志中的result=90是用于拍摄后照片方向修正的计算值,而旧版本camera包的预览旋转逻辑对部分设备的传感器方向适配存在缺陷,导致预览画面未正确应用旋转,因此出现预览异常但照片正常的现象。

内容的提问来源于stack exchange,提问作者Michal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 12:15:04