Xamarin.Forms使用FilePicker选相机拍摄图自动右旋如何解决
问题描述
开发的Xamarin.Forms应用实现两类图片添加功能:
- 调用
FilePicker.PickMultipleAsync从系统相册选择多张图片 - 基于CrossMedia插件实现拍照取图功能
实际运行出现显示异常:
- CrossMedia拍摄的竖屏照片转换为
ImageSource后可正常显示 - 替换为FilePicker选图方案后,执行相同的
ImageSource转换流程时,系统原生相机拍摄的相册图片会自动向右旋转,网络下载后保存到相册的图片无该异常 - 现象对比:互联网下载的图片显示正常,原生相机拍摄后从相册选择的图片存在右旋90度问题
运行环境版本
- Xamarin.Forms: 5.0.0.2401
- Xamarin.Essentials: 1.7.3
原有问题代码
var result = await FilePicker.PickMultipleAsync(new PickOptions { PickerTitle = "Choose Images", FileTypes = FilePickerFileType.Images }); if (result != null) { foreach (var item in result) { AttachedFiles.Add(new AttachmentFiles(item)); } } public AttachmentFiles(FileResult imgSource) { var imageAsBytes = ImageHelper.ConvertStreamToByteArray(Task.Run(async () => await imgSource.OpenReadAsync()).Result); var resizer = DependencyService.Get<IImageResize>(); this.ImageId = Guid.NewGuid(); this.Source = ImageSource.FromStream(() => new MemoryStream(imageAsBytes)); this.SourceT = ImageSource.FromStream(() => new MemoryStream(resizer.ResizeImage(imageAsBytes, 70, 70))); }
问题根因
系统原生相机拍摄的照片会在EXIF元数据中写入拍摄时的设备方向标记,图片实际存储的像素方向不一定和人眼看到的正向一致,展示时需要读取该标记对像素做旋转/翻转校正。
- CrossMedia插件内部默认实现了EXIF方向的自动校正,所以拍照取图显示正常
- FilePicker仅返回原始文件流,不会主动处理EXIF方向标记,原生相机拍摄的照片带方向标记就会出现旋转问题
- 网络下载的图片大多不携带EXIF方向标记,因此不会出现旋转异常
- 原有代码中直接读取原始文件流转字节、做缩放,全程没有处理EXIF方向,最终导致显示旋转。
另外原有代码使用.Result同步阻塞异步调用,存在UI线程死锁风险。
修复方案
- 新增EXIF方向读取与图片校正逻辑:读取图片流时先解析EXIF中的Orientation字段,根据字段值对图片做对应角度的旋转、翻转处理,生成校正后的图片字节数组
- 后续原图绑定、缩略图缩放都基于校正后的字节数组执行,保证原图和缩略图方向一致
- 移除构造函数中的同步阻塞异步调用写法,改为异步初始化方式加载图片,避免死锁
校正逻辑的核心处理对应EXIF方向值的操作:
- Orientation=1:正常方向,无需处理
- Orientation=3:旋转180度
- Orientation=6:顺时针旋转90度(即本次遇到的右旋异常场景)
- Orientation=8:逆时针旋转90度
- 其余值对应水平/垂直翻转+旋转的组合操作,按EXIF标准处理即可
内容的提问来源于stack exchange,提问作者Tiago
相关产品推荐
相关产品推荐

