小程序建议图片大小限制在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;
}
}
}
运行项目既可以看到压缩后的图片。
代码经过运行测试。
浙公网安备 33010602011771号