在日常工作和生活中我们会经常处理一些图片上传到某些网站的事情,一般情况下由于相关网站服务器需要保存图片,但它们又不想占用太大空间就会限制图片的大小,而我们现在手机一般都相素很高,拍出来的图片一般都在十几到几十MB,所以怎么把图片缩小而又不损害图片的质量就成为我们要考虑的问题。今天我就来分享一个用c#实现的高质量图像处理方案,把我们的图像压缩到我们想要的大小而又不损失画面质量的工具。
一、工具概述
本工具基于C# WinForms开发的无损图片批量压缩工具。该工具支持JPG、JPEG、BMP、PNG等常见图片格式,通过设置压缩比例(1%-100%)对图片进行等比例缩放,并采用高质量插值算法确保输出图像品质。
先看界面
我做这个软件的最初目的是处理我手机相册里面所有的文件,所以这里面的图片路径我做的是文件夹,输出也是文件夹。
二、核心代码解读
Graphics高质量渲染三要素,这个是控制图片质量的核心要点,所以这里讲细一点。
g.CompositingQuality = CompositingQuality.HighQuality;g.SmoothingMode = SmoothingMode.HighQuality;g.InterpolationMode = InterpolationMode.HighQualityBicubic;
这三个属性共同决定了图像缩放后的视觉质量。以下详细解析每个属性及其所有枚举值。
该属性控制绘制操作时的颜色混合与合成质量,直接影响透明度混合和颜色叠加的精度。
枚举值 | 说明 |
Invalid | 无效质量 |
Default | 默认质量,平衡性能与质量 |
HighSpeed | 低质量、高速度,适合实时预览 |
HighQuality | 高质量、低速度,使用伽马校正和精确混合 |
GammaCorrected | 启用伽马校正,颜色更真实但性能开销大 |
AssumeLinear | 假设颜色值已经是线性空间,跳过伽马校正 |
当图片包含透明图层(PNG)或进行多重绘图时,HighQuality能避免锯齿边缘和颜色失真。
SmoothingMode(平滑模式)
该属性控制线条和图形边缘的抗锯齿效果,对于图片缩放后的边缘平滑度至关重要。
枚举值 | 说明 |
Invalid | 无效模式 |
Default | 默认模式(等同于None,不清除抗锯齿) |
HighSpeed | 无抗锯齿,最快速度,边缘呈锯齿状 |
HighQuality | 高质量抗锯齿,边缘平滑,性能开销大 |
None | 无抗锯齿 |
AntiAlias | 标准抗锯齿 |
抗锯齿通过在像素边界混合背景色来消除“阶梯效应”。HighQuality会应用更复杂的采样算法,使缩小后的图片边缘更自然
InterpolationMode(插值模式)
这是图片缩放的核心算法,决定像素重采样时如何计算新像素值。该属性对最终画质影响最大。
枚举值 | 算法说明 | 性能 | 质量 |
Default | 默认模式(通常为双线性) | 中 | 中 |
HighSpeed | 最近邻插值,最快但块状感强 | 极快 | 极低 |
HighQualityBicubic | 双三次插值,当前代码使用的模式 | 慢 | 极高 |
Bilinear | 双线性插值,使用周围2×2像素 | 快 | 中 |
Bicubic | 双三次插值,使用周围4×4像素 | 较慢 | 高 |
NearestNeighbor | 最近邻插值,直接取最近像素 | 最快 | 极低 |
Low | 低质量等效于Bilinear | 快 | 低 |
High | 高质量等效于HighQualityBicubic | 慢 | 高 |
当前代码选择 HighQualityBicubic 的理由:在“无损压缩”的语义下,虽然图片尺寸减小了,但每个保留的像素都应该尽可能精确地反映原始图像的采样信息。双三次插值是GDI+中质量最高的内置算法。
通过以上的总结也许你能看的出来,我在做这个绘图的时候各方面的选择都是以质量为第一位,所以我们损失了速度,我想这个在这里并不重要。有得必有舍,只要你不是把这个方法做到高并发的服务器里面就完全没问题。
三、完整代码架构解析
3.1 核心缩放函数 GetPicThumbnail
public static bool GetPicThumbnail(string sFile, string dFile, int dWidth, int dHeight){ if (dWidth <= 0 || dHeight <= 0) return false;
using (Image iSource = Image.FromFile(sFile)) { int sW = 0, sH = 0; if (tem_size.Height > dHeight || tem_size.Width > dWidth) { if ((tem_size.Width * dHeight) > (tem_size.Height * dWidth)) { sW = dWidth; sH = (dWidth * tem_size.Height) / tem_size.Width; } else { sH = dHeight; sW = (tem_size.Width * dHeight) / tem_size.Height; } } else { sW = tem_size.Width; sH = tem_size.Height; }
using (Bitmap oB = new Bitmap(dWidth, dHeight)) { using (Graphics g = Graphics.FromImage(oB)) { g.Clear(Color.WhiteSmoke); g.CompositingQuality = CompositingQuality.HighQuality; g.SmoothingMode = SmoothingMode.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic;
int x = (dWidth - sW) / 2; int y = (dHeight - sH) / 2; g.DrawImage(iSource, new Rectangle(x, y, sW, sH), 0, 0, iSource.Width, iSource.Height, GraphicsUnit.Pixel); }
EncoderParameters eP = new EncoderParameters(1); eP.Param[0] = new EncoderParameter(Encoder.Quality, 100L); oB.Save(dFile, JpegCodecInfo, eP); } }}
这里面重点是要知道:Image的引用是需要释放的;图像缩放要是等比的,不然图片会变形;还要注意是居中显示,并非拉伸显示。这里我用的是JPEG的编码器,如果你需要保持透明度的话需要改为PNG的,但一般处理手机照片是不用的。
3.2 批量处理与进度更新
private void CompleteIMG(){ int totalCount = 0; decimal percentValue = 0;
if (progressBar1.InvokeRequired) { progressBar1.Invoke((Action)(() => { totalCount = al.Count; percentValue = numericUpDown1.Value; })); }
for (int i = 0; i < totalCount; i++) { if (_isCanceling) break;
int newWidth = (int)(tempImg.Width * (percentValue / 100m)); int newHeight = (int)(tempImg.Height * (percentValue / 100m));
GetPicThumbnail(sourceFile, destFile, newWidth, newHeight);
UpdateProgressUI(totalCount, i + 1); }}
这个直接看代码了,没啥说的。其实我也知道手机上看代码有些麻烦,这个源码是分享的,如果有需要可以私信我分享一下。这里面注意一点就是线程安全机制避免界面卡死。
四、压缩比例的逻辑解析
当前实现中,“压缩比例”实际是目标尺寸缩放百分比:
int newWidth = (int)(tempImg.Width * (percentValue / 100m));int newHeight = (int)(tempImg.Height * (percentValue / 100m));
百分比 | 原始尺寸 1920×1080 | 目标尺寸 | 文件大小约减少 |
100% | 1920×1080 | 1920×1080 | 0% |
75% | 1920×1080 | 1440×810 | 约44% |
50% | 1920×1080 | 960×540 | 约75% |
25% | 1920×1080 | 480×270 | 约94% |
这里分辨率以1920*1080为例进行缩放,缩放后的结果也是个大约质,但大差不差。
真正的“无损压缩”通常指保持像素尺寸不变、优化编码算法。本工具的本质是高质量缩略图生成,但由于保留了100%的JPEG质量和最精细的插值算法,在视觉上接近无损感知。
五、总结
本工具通过GDI+的Graphics类实现了高质量的图片批量处理。三个核心渲染属性——CompositingQuality、SmoothingMode、InterpolationMode——共同决定了输出图像的质量等级。选择HighQualityBicubic插值模式配合抗锯齿和伽马校正,即使图片尺寸压缩至50%(节约的是约75%的空间),在常规显示器上依然难以察觉细节损失,实现了“视觉无损”的压缩效果。
阅读原文:https://mp.weixin.qq.com/s/rsKijw8arkrszW9zhPiy5w
该文章在 2026/5/30 16:44:00 编辑过