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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 02:12:31