如何在Flutter中精准获取媒体宽高信息?
问题
我需要执行依赖媒体宽高数据的敏感数学运算,但目前用多种方法获取信息时,频繁出现宽高颠倒的情况:
- 使用FFmpeg插件返回宽750、高2080
- 通过
decodeImageFromList读取文件返回宽2080、高750 - 使用
VideoCompress.getMediaInfo有时返回的结果也和设备图库显示的信息颠倒
手动查看图库存储信息时结果始终正确,现寻求统一的精准获取方法。
代码示例
- 使用
decodeImageFromList的方式:
File fileCreated = File(backgroundImage); final image = await decodeImageFromList(await fileCreated.readAsBytes()); log.log('image width ${image.width}'); log.log('image width ${image.height}');
- 使用VideoCompress的方式:
final info = await VideoCompress.getMediaInfo(videopath); // 输出 w 750 h2080 !! 有时和设备图库显示的数值颠倒
解决方案
宽高颠倒的核心问题是媒体文件携带的旋转元数据(图片的EXIF、视频的轨道旋转信息)未被正确处理——大部分工具返回的是原始像素/编码宽高,但图库会自动根据旋转信息修正显示的宽高,所以才会出现差异。
图片处理方法
decodeImageFromList只会返回原始像素宽高,不会识别EXIF旋转信息。需要额外读取EXIF数据,根据旋转角度调整宽高:
- 借助
exif插件读取图片的旋转方向 - 若旋转角度为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,直接互换宽高即可。
统一处理逻辑
不管图片还是视频,都遵循以下流程:
- 获取工具返回的原始宽高
- 读取旋转元数据,若旋转角度为90°或270°,互换宽高;0°或180°则保持原始宽高
内容的提问来源于stack exchange,提问作者Mohammed Hamdan
相关产品推荐
相关产品推荐

