如何将IFormFile或MemoryStream类型的上传图像统一转换为JPEG格式
实现方案
你之前直接使用ImageFormat转换效果不佳,大多是因为没有处理PNG、GIF这类带透明通道的图片,转JPEG后会出现黑底、色差问题,以下是兼容所有目标格式的正确实现:
依赖说明
如果你使用的是.NET Core/.NET 5+环境,需要先安装NuGet包 System.Drawing.Common:
- Windows环境可直接使用
- Linux环境需要提前安装
libgdiplus依赖库
如果你需要完全跨平台无原生依赖的方案,可以替换为SixLabors.ImageSharp库,逻辑基本一致。
修改后的业务代码
// validate file as image (acceptable formats: jpeg, png, gif, bmp) string FileValidity = FileValidation.VerifyInputFile(imageFile); if (FileValidity != "ok") { _logger.LogInformation("Invalid file uploaded: " + FileValidity); return BadRequest(FileValidity); } // 先将上传的原始文件加载为Image对象 using var originalStream = new MemoryStream(); imageFile.CopyTo(originalStream); originalStream.Position = 0; using var originalImage = Image.FromStream(originalStream); // 新建带白底的画布,处理透明通道问题 using var jpegBitmap = new Bitmap(originalImage.Width, originalImage.Height); using var graphics = Graphics.FromImage(jpegBitmap); graphics.Clear(Color.White); graphics.DrawImage(originalImage, 0, 0, originalImage.Width, originalImage.Height); // 将处理后的图片导出为JPEG格式的流,用于后续预处理 using var jpegStream = new MemoryStream(); // 可自定义JPEG质量,范围1-100,这里设为90兼顾质量和体积 var jpegEncoder = ImageCodecInfo.GetImageEncoders().First(c => c.FormatID == ImageFormat.Jpeg.Guid); var encoderParams = new EncoderParameters(1); encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, 90L); jpegBitmap.Save(jpegStream, jpegEncoder, encoderParams); jpegStream.Position = 0; // 传入JPEG格式的流到预处理方法 string serializedImage = ImagePreprocessing.Preprocess(jpegStream); _logger.LogInformation("Image has been serialized");
注意事项
- 代码中加入了白底填充逻辑,解决了透明图片转JPEG出现黑底的问题
- 支持自定义JPEG压缩质量,可根据业务需求调整
Encoder.Quality对应的数值 - 所有非托管资源都用using块包裹,避免内存泄漏问题
内容的提问来源于stack exchange,提问作者Tommy Tom
相关产品推荐
相关产品推荐

