如何在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
相关产品推荐
相关产品推荐

