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

Flutter图片转Base64后向左旋转90度问题排查与解决求助

图片选择后方向旋转问题的排查与解决

问题描述

我使用chooseImage函数选择图片并将avatar值发送至服务器,目前遇到的问题是:部分图片在处理后会改变原始方向,大多数情况下会向左旋转90度。使用的图片选择插件为image_picker: ^1.0.4,代码如下:

final imageFile = useState<File?>(null);
final avatar = useState('');

Future<void> chooseImage(type) async {
  XFile? image;
  if (type == "camera") {
    image = await ImagePicker().pickImage(source: ImageSource.camera);
  } else {
    image = await ImagePicker().pickImage(source: ImageSource.gallery);
  }
  if (image != null) {
    imageFile.value = File(image.path);
    final bytes = imageFile.value!.readAsBytesSync();
    avatar.value = 
      Uri.dataFromBytes(bytes, mimeType: "appication/png").toString()
    ;
  }
}

问题根源

你的代码直接读取了图片文件的原始字节,但手机拍摄的图片通常会在Exif元信息中记录方向参数,image_picker插件默认不会自动根据Exif信息调整图片的实际像素方向,导致展示或上传时出现旋转偏差。另外代码中mimeType存在拼写错误(appication/png应为application/png),但这不是方向问题的核心原因。

解决方法

需要借助第三方库读取图片的Exif方向信息,并根据参数旋转图片修正方向,推荐使用image库完成图片处理:

  1. 在pubspec.yaml中添加依赖:
dependencies:
  image: ^4.0.17 # 可替换为最新稳定版本
  image_picker: ^1.0.4
  1. 修改chooseImage函数,加入方向修正逻辑:
final imageFile = useState<File?>(null);
final avatar = useState('');

Future<void> chooseImage(type) async {
  XFile? image;
  if (type == "camera") {
    image = await ImagePicker().pickImage(source: ImageSource.camera);
  } else {
    image = await ImagePicker().pickImage(source: ImageSource.gallery);
  }
  if (image != null) {
    // 读取图片字节
    final bytes = await image.readAsBytes();
    final img = decodeImage(bytes);
    if (img != null) {
      // 读取Exif中的方向参数
      final exif = readExifFromBytes(bytes);
      final orientation = exif['Orientation']?.value;
      
      // 根据方向参数修正图片
      Image adjustedImg = img;
      switch (orientation) {
        case 3: // 原始图片需旋转180度
          adjustedImg = copyRotate(img, 180);
          break;
        case 6: // 原始图片需顺时针旋转90度(对应你遇到的向左转90度问题)
          adjustedImg = copyRotate(img, 90);
          break;
        case 8: // 原始图片需逆时针旋转90度
          adjustedImg = copyRotate(img, -90);
          break;
        default:
          adjustedImg = img;
      }
      
      // 将修正后的图片转为字节并生成Data URI
      final adjustedBytes = encodePng(adjustedImg);
      avatar.value = Uri.dataFromBytes(adjustedBytes, mimeType: "application/png").toString();
      
      // 可选:更新imageFile为修正后的文件
      imageFile.value = File.fromRawPath(Uint8List.fromList(adjustedBytes).buffer.asInt8List());
    }
  }
}

补充说明

  • Exif的Orientation参数定义了图片的旋转状态:6代表图片拍摄时是竖向的,需要顺时针旋转90度才能恢复正常显示,这就是你看到图片向左转90度的原因(未处理该参数时,系统会按原始像素方向展示)。
  • 如果需要保留图片的其他Exif元信息,可以配合exif库进行更精细的处理,但对于头像上传场景,上述方案已足够解决方向问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 23:35:12