根据gdi+生成的图片压缩,话不多说,直接上图。另,增加了最终图片大小的设置,
注意,如果不需要优化的话,图片不会挪到你想保存的位置。
另外,destPath,目标保存路径,一定得给保存的文件名字!!不然就会报gdi+一般错误
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
namespace PictureZip
{
static class getHdGraphics
{
/// <summary>
/// 获取高清的Graphics
/// </summary>
/// <param name="img"></param>
/// <returns></returns>
public static Graphics GetGraphics(Image img)
{
var g = Graphics.FromImage(img);
//设置质量
g.SmoothingMode = SmoothingMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
//InterpolationMode不能使用High或者HighQualityBicubic,如果是灰色或者部分浅色的图像是会在边缘处出一白色透明的线
//用HighQualityBilinear却会使图片比其他两种模式模糊(需要肉眼仔细对比才可以看出)
g.InterpolationMode = InterpolationMode.Default;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
return g;
}
/// <summary>
/// 将Image实例保存到文件
/// </summary>
/// <param name="path"></param>
/// <param name="size">保存图片的尺寸,默认最大为4</param>
/// <param name="quality">1~100整数,无效值,则取默认值95</param>
/// <param name="destImage">保存的图片实例</param>
/// <param name="mimeType"></param>
public static void SaveImage2File(string path, Image destImage, int size=4, int quality=95, string mimeType = "image/jpeg")
{
if (quality <= 0 || quality > 100) quality = 95;
//创建保存的文件夹
FileInfo fileInfo = new FileInfo(path);
if (!Directory.Exists(fileInfo.DirectoryName))
{
Directory.CreateDirectory(fileInfo.DirectoryName);
}
//设置保存参数,保存参数里进一步控制质量
EncoderParameters encoderParams = new EncoderParameters();
long[] qua = new long[] { quality };
EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
encoderParams.Param[0] = encoderParam;
//获取指定mimeType的mimeType的ImageCodecInfo
var codecInfo = ImageCodecInfo.GetImageEncoders().FirstOrDefault(ici => ici.MimeType == mimeType);
destImage.Save(path, codecInfo, encoderParams);
FileInfo fileInfo1 = new FileInfo(path);
if(fileInfo1.Length>size*1024*1024)
{
SaveImage2File(path, destImage, size, quality - 2, mimeType);
}
}
/// <summary>
/// 对图片进行压缩优化(限制宽高),始终保持原宽高比
/// </summary>
/// <param name="destPath">目标保存路径</param>
/// <param name="srcPath">源文件路径</param>
/// <param name="size">保存文件大小不超过的值,单位MB,默认最大为4</param>
/// <param name="maxWidth">压缩后的图片宽度不大于这值,如果为0,表示不限制宽度</param>
/// <param name="maxHeight">压缩后的图片高度不大于这值,如果为0,表示不限制高度</param>
/// <param name="quality">1~100整数,无效值则取默认值95</param>
/// <param name="mimeType">如 image/jpeg</param>
/// <param name="error">生成错误返回值</param>
public static bool GetCompressImage(string destPath, string srcPath, int maxWidth, int maxHeight, out string error, int size, int quality=95, string mimeType = "image/jpeg")
{
bool retVal = false;
error = string.Empty;
//宽高不能小于0
if (maxWidth < 0 || maxHeight < 0)
{
error = "目标宽高不能小于0";
return retVal;
}
Image srcImage = null;
Image destImage = null;
Graphics graphics = null;
try
{
//获取源图像
srcImage = Image.FromFile(srcPath, false);
FileInfo fileInfo = new FileInfo(srcPath);
//目标宽度
var destWidth = srcImage.Width;
//目标高度
var destHeight = srcImage.Height;
//如果输入的最大宽为0,则不限制宽度
//如果不为0,且原图宽度大于该值,则附值为最大宽度
if (maxWidth != 0 && destWidth > maxWidth)
{
destWidth = maxWidth;
}
//如果输入的最大宽为0,则不限制宽度
//如果不为0,且原图高度大于该值,则附值为最大高度
if (maxHeight != 0 && destHeight > maxHeight)
{
destHeight = maxHeight;
}
float srcD = (float)srcImage.Height / srcImage.Width;
float destD = (float)destHeight / destWidth;
//目的高宽比 大于 原高宽比 即目的高偏大,因此按照原比例计算目的高度
if (destD > srcD)
{
destHeight = Convert.ToInt32(destWidth * srcD);
}
else if (destD < srcD) //目的高宽比 小于 原高宽比 即目的宽偏大,因此按照原比例计算目的宽度
{
destWidth = Convert.ToInt32(destHeight / srcD);
}
//如果维持原宽高,则判断是否需要优化
if (destWidth == srcImage.Width && destHeight == srcImage.Height && fileInfo.Length < destWidth * destHeight * sizePerPx)
{
error = "图片不需要压缩优化";
return retVal;
}
//定义画布
destImage = new Bitmap(destWidth, destHeight);
//获取高清Graphics
graphics = GetGraphics(destImage);
//将源图像画到画布上,注意最后一个参数GraphicsUnit.Pixel
graphics.DrawImage(srcImage, new Rectangle(0, 0, destWidth, destHeight), new Rectangle(0, 0, srcImage.Width, srcImage.Height), GraphicsUnit.Pixel);
//如果是覆盖则先释放源资源
if (destPath == srcPath)
{
srcImage.Dispose();
}
//保存到文件,同时进一步控制质量
SaveImage2File(destPath, destImage,size,quality,mimeType);
retVal = true;
}
catch (Exception ex)
{
error = ex.Message;
}
finally
{
if (srcImage != null)
srcImage.Dispose();
if (destImage != null)
destImage.Dispose();
if (graphics != null)
graphics.Dispose();
}
return retVal;
}
/// <summary>
/// 对图片进行压缩优化,始终保持原宽高比,限制长边长度,常用场景:相片
/// </summary>
/// <param name="destPath">目标保存路径</param>
/// <param name="srcPath">源文件路径</param>
/// <param name="size">保存文件大小不超过的值,单位MB,默认最大为4</param>
/// <param name="maxLength">压缩后的图片边(宽或者高)长变不大于这值,为0表示不限制</param>
/// <param name="quality">1~100整数,无效值,则取默认值95</param>
/// <param name="error">生成错误返回值</param>
/// <param name="mimeType">如 image/jpeg</param>
public static bool GetCompressImage(string destPath, string srcPath, int maxLength, out string error,int size=4, int quality = 95, string mimeType = "image/jpeg")
{
bool retVal = false;
error = string.Empty;
//最大边长不能小于0
if (maxLength < 0)
{
error = "最大边长不能小于0";
return retVal;
}
Image srcImage = null;
Image destImage = null;
Graphics graphics = null;
try
{
//获取源图像
srcImage = Image.FromFile(srcPath, false);
FileInfo fileInfo = new FileInfo(srcPath);
//目标宽度
var destWidth = srcImage.Width;
//目标高度
var destHeight = srcImage.Height;
//如果限制
if (maxLength > 0)
{
//原高宽比
float srcD = (float)srcImage.Height / srcImage.Width;
//如果宽>高,且大于 限制
if (destWidth > destHeight && destWidth > maxLength)
{
destWidth = maxLength;
destHeight = Convert.ToInt32(destWidth * srcD);
}
else
{
if (destHeight > maxLength)
{
destHeight = maxLength;
destWidth = Convert.ToInt32(destHeight / srcD);
}
}
}
//如果维持原宽高,则判断是否需要优化
if (destWidth == srcImage.Width && destHeight == srcImage.Height && fileInfo.Length < destWidth * destHeight * sizePerPx)
{
error = "图片不需要压缩优化";
return retVal;
}
//定义画布
destImage = new Bitmap(destWidth, destHeight);
//获取高清Graphics
graphics = GetGraphics(destImage);
//将源图像画到画布上,注意最后一个参数GraphicsUnit.Pixel
graphics.DrawImage(srcImage, new Rectangle(0, 0, destWidth, destHeight), new Rectangle(0, 0, srcImage.Width, srcImage.Height), GraphicsUnit.Pixel);
//如果是覆盖则先释放源资源
if (destPath == srcPath)
{
srcImage.Dispose();
}
//保存到文件,同时进一步控制质量
SaveImage2File(destPath, destImage, quality,size,mimeType);
retVal = true;
}
catch (Exception ex)
{
error = ex.Message;
}
finally
{
if (srcImage != null)
srcImage.Dispose();
if (destImage != null)
destImage.Dispose();
if (graphics != null)
graphics.Dispose();
}
return retVal;
}
//优化良好的图片每个像素平均占用文件大小,经验值,可根据需要修改
private static readonly double sizePerPx = 0.18;
/// <summary>
/// 生成高质量缩略图(固定宽高),不一定保持原宽高比
/// </summary>
/// <param name="destPath">目标保存路径</param>
/// <param name="srcPath">源文件路径</param>
/// /// <param name="size">保存文件大小不超过的值,单位MB,默认最大为4</param>
/// <param name="destWidth">生成缩略图的宽度,设置为0,则与源图比处理</param>
/// <param name="destHeight">生成缩略图的高度,设置为0,则与源图等比例处理</param>
/// <param name="quality">1~100整数,无效值则取默认值95</param>
/// <param name="error">生成错误返回值</param>
/// <param name="mimeType">如 image/jpeg</param>
public static bool GetThumbnailImage(string destPath, string srcPath, int destWidth, int destHeight, out string error, int quality=95,int size=4 ,string mimeType = "image/jpeg")
{
bool retVal = false;
error = string.Empty;
//宽高不能小于0
if (destWidth < 0 || destHeight < 0)
{
error = "目标宽高不能小于0";
return retVal;
}
//宽高不能同时为0
if (destWidth == 0 && destHeight == 0)
{
error = "目标宽高不能同时为0";
return retVal;
}
Image srcImage = null;
Image destImage = null;
Graphics graphics = null;
try
{
//获取源图像
srcImage = Image.FromFile(srcPath, false);
//计算高宽比例
float d = (float)srcImage.Height / srcImage.Width;
//如果输入的宽为0,则按高度等比缩放
if (destWidth == 0)
{
destWidth = Convert.ToInt32(destHeight / d);
}
//如果输入的高为0,则按宽度等比缩放
if (destHeight == 0)
{
destHeight = Convert.ToInt32(destWidth * d);
}
//定义画布
destImage = new Bitmap(destWidth, destHeight);
//获取高清Graphics
graphics = GetGraphics(destImage);
//将源图像画到画布上,注意最后一个参数GraphicsUnit.Pixel
graphics.DrawImage(srcImage, new Rectangle(0, 0, destWidth, destHeight), new Rectangle(0, 0, srcImage.Width, srcImage.Height), GraphicsUnit.Pixel);
//如果是覆盖则先释放源资源
if (destPath == srcPath)
{
srcImage.Dispose();
}
//保存到文件,同时进一步控制质量
SaveImage2File(destPath, destImage, 4,quality,mimeType);
retVal = true;
}
catch (Exception ex)
{
error = ex.Message;
}
finally
{
if (srcImage != null)
srcImage.Dispose();
if (destImage != null)
destImage.Dispose();
if (graphics != null)
graphics.Dispose();
}
return retVal;
}
}
}
转载于:https://blog.csdn.net/lhtzbj12/article/details/54099246
转载于:https://blog.csdn.net/lhtzbj12/article/details/54143044