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

如何在Flutter中精准获取媒体宽高信息?

问题

我需要执行依赖媒体宽高数据的敏感数学运算,但目前用多种方法获取信息时,频繁出现宽高颠倒的情况:

  • 使用FFmpeg插件返回宽750、高2080
  • 通过decodeImageFromList读取文件返回宽2080、高750
  • 使用VideoCompress.getMediaInfo有时返回的结果也和设备图库显示的信息颠倒

手动查看图库存储信息时结果始终正确,现寻求统一的精准获取方法。

代码示例

  1. 使用decodeImageFromList的方式:
File fileCreated = File(backgroundImage);
final image = await decodeImageFromList(await fileCreated.readAsBytes());
log.log('image width ${image.width}');
log.log('image width ${image.height}');
  1. 使用VideoCompress的方式:
final info = await VideoCompress.getMediaInfo(videopath);
// 输出 w 750 h2080 !! 有时和设备图库显示的数值颠倒

解决方案

宽高颠倒的核心问题是媒体文件携带的旋转元数据(图片的EXIF、视频的轨道旋转信息)未被正确处理——大部分工具返回的是原始像素/编码宽高,但图库会自动根据旋转信息修正显示的宽高,所以才会出现差异。

图片处理方法

decodeImageFromList只会返回原始像素宽高,不会识别EXIF旋转信息。需要额外读取EXIF数据,根据旋转角度调整宽高:

  1. 借助exif插件读取图片的旋转方向
  2. 若旋转角度为90°或270°,直接互换原始宽高即可

示例代码:

import 'package:exif/exif.dart';

Future<Map<String, int>> getRealImageSize(String imagePath) async {
  final file = File(imagePath);
  final bytes = await file.readAsBytes();
  final exifData = await readExifFromBytes(bytes);
  
  // 获取原始像素宽高
  final image = await decodeImageFromList(bytes);
  int width = image.width;
  int height = image.height;
  
  // 读取EXIF中的旋转方向
  final orientation = exifData['Orientation']?.printable;
  if (orientation == 'Rotate 90 CW' || orientation == 'Rotate 270 CW') {
    // 旋转90/270度时,宽高互换
    final temp = width;
    width = height;
    height = temp;
  }
  
  return {'width': width, 'height': height};
}

视频处理方法

视频的旋转信息存储在轨道元数据中,VideoCompress或FFmpeg返回的是编码原始宽高,需结合旋转角度修正:

  • 若旋转角度为90°或270°,互换原始宽高即可得到图库显示的实际尺寸
  • 若插件未直接返回旋转角度,用FFmpeg命令读取最精准

用VideoCompress的处理示例:

Future<Map<String, int>> getRealVideoSize(String videoPath) async {
  final info = await VideoCompress.getMediaInfo(videoPath);
  int width = info.width;
  int height = info.height;
  
  // 读取视频旋转角度(部分版本的VideoCompress会直接提供该字段)
  final rotation = info.rotation ?? 0;
  if (rotation == 90 || rotation == 270) {
    final temp = width;
    width = height;
    height = temp;
  }
  
  return {'width': width, 'height': height};
}

用FFmpeg获取精准信息的命令:

ffmpeg -i 你的视频路径 -v error -select_streams v:0 -show_entries stream=width,height,rotation -of default=nw=1:nk=1

输出中若rotation为90或270,直接互换宽高即可。

统一处理逻辑

不管图片还是视频,都遵循以下流程:

  1. 获取工具返回的原始宽高
  2. 读取旋转元数据,若旋转角度为90°或270°,互换宽高;0°或180°则保持原始宽高

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 07:16:18