高效的图片压缩代码,直接复制粘贴就能用

根据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

猜你喜欢

转载自blog.csdn.net/weixin_36179862/article/details/80311424