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

Xamarin iOS端如何压缩FileResult以缩短Base64长度?

Xamarin iOS 头像图片压缩方案(解决Base64过长无法存入数据库问题)

方案一:使用SkiaSharp(跨平台推荐)

SkiaSharp是谷歌推出的跨平台图形库,适配Xamarin.Forms项目,能灵活控制图片尺寸与压缩质量,稳定性强。

操作步骤:

  1. 安装NuGet包:SkiaSharp 和 SkiaSharp.Views.Forms
  2. 修改你的CapturePhoto方法如下:
using SkiaSharp;

async Task CapturePhoto()
{
    try
    {
        var result = await MediaPicker.CapturePhotoAsync();

        if (result != null)
        {
            using (var stream = await result.OpenReadAsync())
            using (var originalBitmap = SKBitmap.Decode(stream))
            {
                // 定义目标头像宽度(可按需调整,200px足够满足大多数场景)
                int targetWidth = 200;
                // 按原比例计算目标高度,避免图片拉伸变形
                int targetHeight = (int)((float)originalBitmap.Height / originalBitmap.Width * targetWidth);
                targetHeight = targetHeight == 0 ? targetWidth : targetHeight;

                // 缩放图片,平衡清晰度与性能
                using (var resizedBitmap = originalBitmap.Resize(new SKImageInfo(targetWidth, targetHeight), SKFilterQuality.Medium))
                using (var image = SKImage.FromBitmap(resizedBitmap))
                using (var compressedStream = new MemoryStream())
                {
                    // 以JPEG格式压缩,质量值0-100(值越小压缩率越高,70为清晰度与压缩率的平衡点)
                    var encodedData = image.Encode(SKEncodedImageFormat.Jpeg, 70);
                    encodedData.SaveTo(compressedStream);
                    compressedStream.Position = 0;

                    byte[] compressedBytes = compressedStream.ToArray();
                    string base64 = Convert.ToBase64String(compressedBytes);
                    profil.Photo = base64;
                    // 直接用压缩后的字节流显示图片,无需重复转Base64,提升性能
                    ImageProfil.Source = ImageSource.FromStream(() => new MemoryStream(compressedBytes));
                    Console.WriteLine($"压缩后Base64长度:{base64.Length}");
                }
            }
        }
    }
    catch (Exception e)
    {
        await DisplayAlert("Erreur", e.Message, "ok");
    }
}

方案二:iOS原生API压缩(仅iOS平台)

如果你的应用仅面向iOS平台,可直接使用UIKit原生API压缩,性能更优。

操作步骤:

  1. 在iOS项目中添加压缩工具类:
using UIKit;
using CoreGraphics;

public static class ImageCompressor
{
    public static byte[] CompressImage(byte[] originalData, int targetWidth = 200, int quality = 70)
    {
        using (var uiImage = UIImage.LoadFromData(NSData.FromArray(originalData)))
        {
            // 计算缩放比例
            float scale = (float)targetWidth / uiImage.Size.Width;
            var newSize = new CGSize(targetWidth, uiImage.Size.Height * scale);

            // 绘制并压缩图片
            UIGraphics.BeginImageContextWithOptions(newSize, false, 1.0f);
            uiImage.Draw(new CGRect(0, 0, newSize.Width, newSize.Height));
            var compressedImage = UIGraphics.GetImageFromCurrentImageContext();
            UIGraphics.EndImageContext();

            // 转为JPEG字节数组
            var compressedData = compressedImage.AsJPEG((nfloat)quality / 100);
            return compressedData.ToArray();
        }
    }
}
  1. 在共享项目中调用该方法:
async Task CapturePhoto()
{
    try
    {
        var result = await MediaPicker.CapturePhotoAsync();

        if (result != null)
        {
            using (var stream = await result.OpenReadAsync())
            using (var memoryStream = new MemoryStream())
            {
                stream.CopyTo(memoryStream);
                byte[] originalBytes = memoryStream.ToArray();
                
                // 调用iOS原生压缩方法
                byte[] compressedBytes = ImageCompressor.CompressImage(originalBytes);
                string base64 = Convert.ToBase64String(compressedBytes);
                profil.Photo = base64;
                ImageProfil.Source = ImageSource.FromStream(() => new MemoryStream(compressedBytes));
                Console.WriteLine($"压缩后Base64长度:{base64.Length}");
            }
        }
    }
    catch (Exception e)
    {
        await DisplayAlert("Erreur", e.Message, "ok");
    }
}

额外优化建议

  • 拍照前可通过MediaPickerOptions限制原始照片尺寸,进一步减少初始数据量:
var result = await MediaPicker.CapturePhotoAsync(new MediaPickerOptions
{
    PhotoSize = PhotoSize.Medium // 可选Small/Medium/Large,或自定义尺寸
});
  • 测试调整压缩质量值(60-80区间),找到适合你场景的清晰度与压缩率平衡点

内容的提问来源于stack exchange,提问作者Antoine21000

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 13:53:25