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

如何在Xamarin中实现图片调整大小、格式转换及压缩功能

Xamarin图片选择、调整尺寸及压缩上传实现方案

一、图片尺寸调整可行实现方案

不要依赖不兼容Xamarin的System.Drawing库,推荐使用微软官方维护的SkiaSharp跨平台2D图形库,完全兼容Xamarin全平台,也支持HEIC格式解码,无需拆分平台单独写代码。
参考实现代码:

using SkiaSharp;

/// <summary>
/// 等比例缩放图片,宽高均不超过最大限制
/// </summary>
public byte[] ResizeImage(byte[] originalImageBytes, int maxWidthHeight = 1500)
{
    using var originalStream = new MemoryStream(originalImageBytes);
    using var originalBitmap = SKBitmap.Decode(originalStream);
    
    // 计算缩放比例,保持宽高比
    var scale = Math.Min((float)maxWidthHeight / originalBitmap.Width, (float)maxWidthHeight / originalBitmap.Height);
    
    // 原尺寸符合要求直接返回,不做额外处理
    if (scale <= 1) return originalImageBytes;
    
    var newWidth = (int)(originalBitmap.Width * scale);
    var newHeight = (int)(originalBitmap.Height * scale);
    
    using var resizedBitmap = originalBitmap.Resize(new SKImageInfo(newWidth, newHeight), SKFilterQuality.High);
    using var image = SKImage.FromBitmap(resizedBitmap);
    // 先输出无损字节流转给压缩逻辑
    return image.Encode(SKEncodedImageFormat.Png, 100).ToArray();
}

二、JPG压缩方案评估及优化

你设计的循环降质量方案是合理的:逻辑简单可靠,能在满足大小限制的前提下保留最优画质,符合你的业务需求。仅存在极端场景下多次压缩占用资源的小问题,可以做以下优化:

  • 先做尺寸调整再执行压缩:宽高限制在1500px后,90%以上的场景100%质量的JPG大小已经低于2MB,无需再降质量,大幅减少不必要的压缩操作
  • 优化质量调整逻辑,避免逐次5%递减:可以根据首次100%质量导出的文件大小,直接计算出近似的目标质量,再微调,最多2-3次就能找到符合要求的最高质量,减少循环次数
  • 前置大小校验:只要尺寸调整后的100%质量JPG符合大小要求,直接返回,完全不会损耗原本合格文件的画质

参考实现代码:

/// <summary>
/// 压缩为JPG格式,不超过指定大小
/// </summary>
public byte[] CompressToJpgWithSizeLimit(byte[] imageBytes, int maxSizeInBytes = 2 * 1024 * 1024)
{
    int quality = 100;
    byte[] resultBytes;
    
    using var originalStream = new MemoryStream(imageBytes);
    using var bitmap = SKBitmap.Decode(originalStream);
    using var image = SKImage.FromBitmap(bitmap);
    
    // 先尝试100%质量
    using (var data = image.Encode(SKEncodedImageFormat.Jpeg, quality))
    {
        resultBytes = data.ToArray();
    }
    if (resultBytes.Length <= maxSizeInBytes) return resultBytes;
    
    // 计算近似初始质量,减少循环次数
    quality = (int)Math.Floor((double)maxSizeInBytes / resultBytes.Length * 100);
    
    // 逐次降3%比5%更容易找到最优画质
    while (quality > 0)
    {
        using var data = image.Encode(SKEncodedImageFormat.Jpeg, quality);
        resultBytes = data.ToArray();
        if (resultBytes.Length <= maxSizeInBytes) break;
        quality -= 3;
    }
    
    return resultBytes;
}

关于PickPhotoAsync()的质量参数:该参数的压缩比例没有统一标准,不同设备、不同原始文件的压缩结果差异极大,确实无法保证输出大小符合要求,自行控制压缩逻辑稳定性更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 04:51:00