小程序建议图片大小限制在200kb以内,故而需要将图片的大小无损压缩到200kb以内。
用C#写了下代码实现图片的压缩(你可以设置需要压缩的图片的大小)
1. 前端代码 Index.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="WebApplication5.Index" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> </head> <body> <form id="form1" runat="server"> <div> <table> <tr> <td>原始图片:</td> <td> <asp:Image ID="Image1" runat="server" /> </td> </tr> <tr> <td>压缩图片:</td> <td> <asp:Image ID="Image2" runat="server" /> </td> </tr> </table> </div> </form> </body> </html>
2. 后端代码 Index.aspx.cs
using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; namespace WebApplication5 { public partial class Index : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { string sourceFileName = "details_01.png"; Image1.ImageUrl = sourceFileName; string sourcePath = Server.MapPath("~/") + sourceFileName;//图片原路径 //获取后缀 string extname = Path.GetExtension(sourcePath);//获取文件的拓展名称 string newFileName = Guid.NewGuid().ToString().Substring(0, 6) + extname; string newPath = Server.MapPath("~/") + newFileName; CompressImage(sourcePath, newPath); Image2.ImageUrl = newFileName; } } /// <summary> /// 无损压缩图片(默认为 不超过200kb) /// </summary> /// <param name="sourceFile">原图片地址</param> /// <param name="newFile">压缩后保存图片地址</param> /// <param name="size">压缩后图片的最大大小 默认为 不超过200kb</param> /// <returns></returns> public void CompressImage(string sourceFile, string newFile, int size = 200) { //设置大小偏差幅度 1kb const long nearlyLen = 1024; //如果是第一次调用,原始图像的大小小于要压缩的大小,则直接复制文件,并且返回true FileInfo firstFileInfo = new FileInfo(sourceFile); long sourceLen = firstFileInfo.Length; //原始大小 long targetLen = size * 1024; //压缩后大小 if (sourceLen <= targetLen) { firstFileInfo.CopyTo(newFile); } else { //获取目标大小最低值 var exitLen = targetLen - nearlyLen; using (System.Drawing.Image iSource = System.Drawing.Image.FromFile(sourceFile)) { ImageFormat sourceFormat = iSource.RawFormat; //图片格式 int sourceHeight = iSource.Height; int sourceWidth = iSource.Width; int sW = 0, sH = 0; //按比例缩放 Size tem_size = new Size(sourceWidth, sourceHeight); if (tem_size.Width > sourceHeight || tem_size.Width > sourceWidth) { if ((tem_size.Width * sourceHeight) > (tem_size.Width * sourceWidth)) { sW = sourceWidth; sH = (sourceWidth * tem_size.Height) / tem_size.Width; } else { sH = sourceHeight; sW = (tem_size.Width * sourceHeight) / tem_size.Height; } } else { sW = tem_size.Width; sH = tem_size.Height; } using (Bitmap ob = new Bitmap(sourceWidth, sourceHeight)) { using (Graphics g = Graphics.FromImage(ob)) { g.Clear(Color.WhiteSmoke); g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.DrawImage(iSource, new Rectangle((sourceWidth - sW) / 2, (sourceHeight - sH) / 2, sW, sH), 0, 0, iSource.Width, iSource.Height, GraphicsUnit.Pixel); } //获取编码器信息 var format = ImageFormat.Jpeg; ImageCodecInfo formatInfo = GetEncoder(format); if (formatInfo != null) { //以下代码为保存图片时,设置压缩质量 var parms = new EncoderParameters(1); //初始化质量压缩参数 压缩质量(数字越小压缩率越高)1-100 var quality = (long)Math.Floor(100.00 * targetLen / sourceLen); //使用二分法进行查找 最接近的质量参数 long startQuality = quality; long endQuality = 100; using (var ms = new MemoryStream()) { while (true) { parms.Param[0] = new EncoderParameter(Encoder.Quality, quality); ms.SetLength(0); ms.Position = 0; ob.Save(ms, formatInfo, parms); long newImageLen = ms.Length; //若压缩后大小低于目标大小,则满足条件退出 if (newImageLen >= exitLen && newImageLen <= targetLen) { break; } else { //区间相等无需再次计算 if (startQuality >= endQuality) { break; } else { if (newImageLen < exitLen) //压缩过小,起始质量右移 { startQuality = quality; } else //压缩过大 终止质量左移 { endQuality = quality; } //重新设置质量参数 如果计算出来的质量没有发生变化,则终止查找。这样是为了避免重复计算情况{start:16,end:18} 和 {start:16,endQuality:17} long newQuality = (startQuality + endQuality) / 2; if (newQuality == quality) { break; } else { quality = newQuality; } } } } } ob.Save(newFile, formatInfo, parms);//dFile是压缩后的新路径 } else { ob.Save(newFile, sourceFormat); } } } } } /// <summary> /// 获取编码器信息 /// </summary> /// <param name="format"></param> /// <returns></returns> private ImageCodecInfo GetEncoder(ImageFormat format) { ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders(); foreach (ImageCodecInfo codec in codecs) { if (codec.FormatID == format.Guid) { return codec; } } return null; } } }
运行项目既可以看到压缩后的图片。
代码经过运行测试。