1. 程式人生 > >高效的圖片壓縮程式碼,直接複製貼上就能用

高效的圖片壓縮程式碼,直接複製貼上就能用

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