Xamarin Essentials MediaPicker的CapturePhotoAsync真机图片旋转问题求助
解决方案:MediaPicker拍照后真机图片旋转问题
这不是Xamarin Essentials的Bug,问题出在真机拍摄的照片会在EXIF元数据中记录拍摄时的旋转角度,而SkiaSharp默认解码时不会自动应用这个旋转信息,模拟器因为没有真实的传感器数据,不会产生这类旋转元数据,因此显示正常。
以下是修复代码,核心是读取照片的EXIF旋转角度,手动将位图旋转到正确方向:
修改后的拍照方法
private async void Capture_Photo(object sender, EventArgs e) { var result = await MediaPicker.CapturePhotoAsync(); if (result != null) { using var stream = await result.OpenReadAsync(); // 通过SKCodec获取照片编码信息,提取EXIF旋转角度 var codec = SKCodec.Create(stream); var rotationAngle = GetExifRotationAngle(codec); // 解码原始位图 statBitmap = SKBitmap.Decode(codec); // 如果存在旋转角度,对位图进行旋转修正 if (rotationAngle != 0) { using var rotatedBitmap = statBitmap.RotateDegrees(rotationAngle); // 释放原始位图,避免内存泄漏 statBitmap.Dispose(); statBitmap = rotatedBitmap.Copy(); } } }
提取EXIF旋转角度的辅助方法
private int GetExifRotationAngle(SKCodec codec) { // 仅JPEG格式照片通常包含EXIF旋转信息,其他格式可根据需求扩展 var exifData = codec.EncodedFormat == SKEncodedFormat.Jpeg ? codec.GetExifData() : null; if (exifData == null) return 0; // 遍历EXIF标签,找到Orientation标签(ID为274) foreach (var tag in exifData) { if (tag.TagId == 274) { // 根据Orientation值返回对应的旋转角度 return tag.Value switch { 1 => 0, // 正常方向 3 => 180, // 顺时针旋转180° 6 => 90, // 顺时针旋转90° 8 => 270, // 顺时针旋转270° // 其他翻转类的Orientation值可根据业务需求处理,这里默认返回0 _ => 0 }; } } return 0; }
关键说明
- 使用
SKCodec而非直接解码流,是为了读取EXIF元数据; - 旋转位图后要释放原始
SKBitmap实例,防止内存泄漏; - 不同的Orientation值对应不同的旋转/翻转逻辑,可根据实际显示需求调整返回的角度。
内容的提问来源于stack exchange,提问作者Victor
相关产品推荐
相关产品推荐

