Xamarin Forms安卓真机拍照后图片向左旋转90度问题求助
解决Xamarin Forms真机拍照图片旋转90度问题
问题原因
安卓物理设备拍摄照片时,会将设备的旋转角度信息存入图片的EXIF元数据中,但Xamarin Forms的MediaPicker组件不会自动读取并应用这个旋转信息,导致图片按原始像素方向显示,出现向左旋转90度的情况;而模拟器的相机通常不会写入这类EXIF旋转数据,所以显示正常。
解决方案
使用SkiaSharp库读取图片的EXIF旋转信息,手动调整图片方向后再转为byte数组。SkiaSharp是跨平台的图形处理库,能方便处理图片和EXIF数据。
步骤1:安装NuGet包
在项目中安装SkiaSharp包:
Install-Package SkiaSharp
步骤2:修改拍照处理代码
替换原代码中读取图片流并转为byte数组的逻辑,加入旋转处理:
private async void ChangePic(object sender, EventArgs e) { string action = await DisplayActionSheet("Change Picture", "Cancel", null, "Take Photo", "Choose from Library"); if (action == "Take Photo") { var options = new MediaPickerOptions { Title = "Take Photo" }; var photo = await MediaPicker.CapturePhotoAsync(options); if (photo != null) { using (var stream = await photo.OpenReadAsync()) { profPicture = await ProcessImageRotation(stream); } pictureImage.Source = ImageSource.FromStream(() => new MemoryStream(profPicture)); } } else if (action == "Choose from Library") { // 原有逻辑... } } // 处理图片旋转的核心方法 private async Task<byte[]> ProcessImageRotation(Stream imageStream) { imageStream.Position = 0; using (var bitmap = SKBitmap.Decode(imageStream)) { // 获取EXIF中的旋转角度 int rotationDegrees = GetExifRotation(imageStream); if (rotationDegrees != 0) { using (var rotatedBitmap = RotateBitmap(bitmap, rotationDegrees)) { using (var outputStream = new MemoryStream()) { rotatedBitmap.Encode(SKEncodedImageFormat.Jpeg, 90).SaveTo(outputStream); return outputStream.ToArray(); } } } else { using (var outputStream = new MemoryStream()) { bitmap.Encode(SKEncodedImageFormat.Jpeg, 90).SaveTo(outputStream); return outputStream.ToArray(); } } } } // 读取EXIF旋转角度 private int GetExifRotation(Stream stream) { stream.Position = 0; using (var exifReader = new SKExifMetadataReader(stream)) { var orientationTag = exifReader.GetTagValue(SKExifTag.Orientation); if (orientationTag != null) { switch ((int)orientationTag.Value) { case 3: return 180; case 6: return 90; case 8: return 270; default: return 0; } } } return 0; } // 旋转Bitmap private SKBitmap RotateBitmap(SKBitmap originalBitmap, int degrees) { // 旋转后图片宽高互换 var rotatedBitmap = new SKBitmap( degrees == 90 || degrees == 270 ? originalBitmap.Height : originalBitmap.Width, degrees == 90 || degrees == 270 ? originalBitmap.Width : originalBitmap.Height ); using (var canvas = new SKCanvas(rotatedBitmap)) { var matrix = new SKMatrix(); matrix.SetRotateDegrees(degrees, rotatedBitmap.Width / 2f, rotatedBitmap.Height / 2f); canvas.SetMatrix(matrix); canvas.DrawBitmap(originalBitmap, 0, 0); } return rotatedBitmap; }
说明
GetExifRotation方法读取EXIF的Orientation标签,映射为对应的旋转角度;RotateBitmap方法根据旋转角度创建新的Bitmap,通过画布旋转绘制实现图片方向调整;- 处理后的图片会自动应用正确的旋转角度,无论是模拟器还是真机都能正常显示。
内容的提问来源于stack exchange,提问作者bluedra
相关产品推荐
相关产品推荐

