LOGO 首页 OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 技术文档 其他文档  
 
网站管理员

【.net】无损图片压缩工具:C#实现的高质量图像处理方案

admin
2026年5月30日 16:44 本文热度 84
在日常工作和生活中我们会经常处理一些图片上传到某些网站的事情,一般情况下由于相关网站服务器需要保存图片,但它们又不想占用太大空间就会限制图片的大小,而我们现在手机一般都相素很高,拍出来的图片一般都在十几到几十MB,所以怎么把图片缩小而又不损害图片的质量就成为我们要考虑的问题。

今天我就来分享一个用c#实现的高质量图像处理方案,把我们的图像压缩到我们想要的大小而又不损失画面质量的工具。

一、工具概述

本工具基于C# WinForms开发的无损图片批量压缩工具。该工具支持JPG、JPEG、BMP、PNG等常见图片格式,通过设置压缩比例(1%-100%)对图片进行等比例缩放,并采用高质量插值算法确保输出图像品质。

先看界面

我做这个软件的最初目的是处理我手机相册里面所有的文件,所以这里面的图片路径我做的是文件夹,输出也是文件夹。

二、核心代码解读

Graphics高质量渲染三要素,这个是控制图片质量的核心要点,所以这里讲细一点。

// 设置画布的描绘质量g.CompositingQuality = CompositingQuality.HighQuality;g.SmoothingMode = SmoothingMode.HighQuality;g.InterpolationMode = InterpolationMode.HighQualityBicubic;

这三个属性共同决定了图像缩放后的视觉质量。以下详细解析每个属性及其所有枚举值。

  1. CompositingQuality(合成质量)

    该属性控制绘制操作时的颜色混合与合成质量,直接影响透明度混合和颜色叠加的精度。

    枚举值

    说明

    Invalid

    无效质量

    Default

    默认质量,平衡性能与质量

    HighSpeed

    低质量、高速度,适合实时预览

    HighQuality

    高质量、低速度,使用伽马校正和精确混合

    GammaCorrected

    启用伽马校正,颜色更真实但性能开销大

    AssumeLinear

    假设颜色值已经是线性空间,跳过伽马校正

    当图片包含透明图层(PNG)或进行多重绘图时,HighQuality能避免锯齿边缘和颜色失真。

  2. SmoothingMode(平滑模式)

    该属性控制线条和图形边缘的抗锯齿效果,对于图片缩放后的边缘平滑度至关重要。

    枚举值

    说明

    Invalid

    无效模式

    Default

    默认模式(等同于None,不清除抗锯齿)

    HighSpeed

    无抗锯齿,最快速度,边缘呈锯齿状

    HighQuality

    高质量抗锯齿,边缘平滑,性能开销大

    None

    无抗锯齿

    AntiAlias

    标准抗锯齿

    抗锯齿通过在像素边界混合背景色来消除“阶梯效应”。HighQuality会应用更复杂的采样算法,使缩小后的图片边缘更自然

  3. 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){    // 1. 参数校验    if (dWidth <= 0 || dHeight <= 0return false;
    using (Image iSource = Image.FromFile(sFile))    {        // 2. 计算缩放后的实际尺寸(等比例)        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;        }
        // 3. 创建目标位图并设置高质量渲染        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),                             00, iSource.Width, iSource.Height, GraphicsUnit.Pixel);            }
            // 4. 保存并设置JPEG压缩质量为100            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(){    // 安全读取UI控件值(跨线程访问)    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);
        // 更新进度UI        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类实现了高质量的图片批量处理。三个核心渲染属性——CompositingQualitySmoothingModeInterpolationMode——共同决定了输出图像的质量等级。选择HighQualityBicubic插值模式配合抗锯齿和伽马校正,即使图片尺寸压缩至50%(节约的是约75%的空间),在常规显示器上依然难以察觉细节损失,实现了“视觉无损”的压缩效果。

阅读原文:https://mp.weixin.qq.com/s/rsKijw8arkrszW9zhPiy5w


该文章在 2026/5/30 16:44:00 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved  粤ICP备13012886号-9  粤公网安备44030602007207号