C#调整JPG图片尺寸结果不符预期且文件大小异常增大问题咨询
问题1:输出高度超出512px的原因
你的ResizeImage方法的尺寸计算逻辑存在漏洞:
- 测试用原图宽536px、高589px,宽高比为
536/589≈0.91<1,匹配第一个if分支的判断条件 - 该分支仅做了「原图宽度超过maxWidth时将宽度限制为512px」的处理,直接按比例计算得到高度≈536px,完全没有校验计算出的高度是否超过maxHeight限制
- 原始逻辑采用互斥分支判断,只能覆盖「仅宽度超限」或「仅高度超限」的场景,无法处理「单维度压缩后另一维度仍超限」的竖图/横图场景。正确逻辑应该是分别计算宽、高维度的缩放比例,取最小值作为实际缩放系数,保证两个维度都不超过限制值。
问题2:输出文件大小远大于原图的原因
- .NET的
Bitmap.Save方法默认保存JPG格式时,默认使用100%质量等级编码,压缩率极低 - 原图本身是经过高压缩比处理的130KB文件,重新编码时使用了低压缩率参数,即便分辨率低于原图,最终存储体积也会大幅上升
- 额外的内存泄漏隐患:原有代码
Bitmap bmp1 = new Bitmap(ResizeImage(file, 512, 512));多嵌套了一层Bitmap实例化,会导致ResizeImage返回的Bitmap对象未被释放,也可能产生额外的冗余数据。
修复代码
1. 修复尺寸计算逻辑的ResizeImage方法
private static Bitmap ResizeImage(String filename, int maxWidth, int maxHeight) { using (Image originalImage = Image.FromFile(filename)) { // 分别计算宽高的缩放比例,取最小值保证两个维度都不超限 double scaleRatio = Math.Min((double)maxWidth / originalImage.Width, (double)maxHeight / originalImage.Height); // 原图尺寸小于限制则无需缩放 if (scaleRatio >= 1) { return new Bitmap(originalImage); } int newWidth = (int)Math.Round(originalImage.Width * scaleRatio); int newHeight = (int)Math.Round(originalImage.Height * scaleRatio); Bitmap newImage = new Bitmap(newWidth, newHeight); using (Graphics g = Graphics.FromImage(newImage)) { g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; g.DrawImage(originalImage, 0, 0, newImage.Width, newImage.Height); return newImage; } } }
2. 修复保存逻辑,指定JPEG压缩质量
首先定义获取JPEG编码器的辅助方法:
private static ImageCodecInfo GetJpegCodec() { return ImageCodecInfo.GetImageEncoders().FirstOrDefault(c => c.FormatID == ImageFormat.Jpeg.Guid); }
修改backgroundWorker1_DoWork方法:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { try { BackgroundWorker worker = sender as BackgroundWorker; int counter = 0; int percentage = 0; // 提前定义JPEG编码参数,质量值范围0-100,可根据体积需求调整 ImageCodecInfo jpegCodec = GetJpegCodec(); EncoderParameters encoderParams = new EncoderParameters(1); encoderParams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 75L); foreach (string file in files) { // 用using自动释放Bitmap资源,去掉多余的new Bitmap嵌套 using (Bitmap bmp1 = ResizeImage(file, 512, 512)) { string resizedfilename = Path.Combine(directoryPath, Path.GetFileNameWithoutExtension(file) + "_resized.jpg"); // 指定JPEG编码参数保存 bmp1.Save(resizedfilename, jpegCodec, encoderParams); } counter++; percentage = counter * 100 / files.Length; worker.ReportProgress(percentage); } } catch(Exception err) { // 可自行添加异常日志逻辑 } }
内容的提问来源于stack exchange,提问作者Daniel Lip
相关产品推荐
相关产品推荐

