高效的圖片壓縮程式碼,直接複製貼上就能用
阿新 • • 發佈:2018-11-25
根據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