[C#] 等比例縮圖的程式碼

[C#] 等比例縮圖的程式碼

前言

把一張圖片,等比例縮圖目的:

1. 縮小並維持圖片比例,避免破壞美觀

2. 縮小圖片,減少存取流量

 

假設圖片長度不得超過220px

分三種方法

第一種,寬高誰較長就縮誰

第二種,寬度維持220,高度等比例縮放

第三種,高度維持220,寬度等比例縮放

 

實作

以下是Console Application,說明在註解裡

※image.GetThumbnailImage()對於某些圖片(什麼特徵目前還沒查出XD)會嚴重破壞壓縮,導致縮圖後的品質變差↓,請勿使用,最新寫法請參考文章底下


using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        //使用方法
        static void Main(string[] args)
        {
            string path = @"D:\source.jpg";
            SaveThumbPicWidth(path, 220, @"D:\width.jpg");
            SaveThumbPicHeight(path, 220, @"D:\height.jpg");
            SaveThumbPic(path, 220, @"D:\unknown.jpg");
        }


        #region  取得圖片等比例縮圖後的寬和高像素
        /// <summary>
        ///  寬高誰較長就縮誰  - 計算方法
        /// </summary>
        /// <param name="image">System.Drawing.Image 的物件</param>
        /// <param name="maxPx">寬或高超過多少像素就要縮圖</param>
        /// <returns>回傳int陣列,索引0為縮圖後的寬度、索引1為縮圖後的高度</returns>
        public static int[] GetThumbPic_WidthAndHeight(System.Drawing.Image image, int maxPx)
        {

            int fixWidth = 0;

            int fixHeight = 0;

            if (image.Width > maxPx || image.Height > maxPx)
            //如果圖片的寬大於最大值或高大於最大值就往下執行  
            {

                if (image.Width >= image.Height)
                //圖片的寬大於圖片的高  
                {

                    fixHeight = Convert.ToInt32((Convert.ToDouble(maxPx) / Convert.ToDouble(image.Width)) * Convert.ToDouble(image.Height));
                    //設定修改後的圖高  
                    fixWidth = maxPx;
                }
                else
                {

                    fixWidth = Convert.ToInt32((Convert.ToDouble(maxPx) / Convert.ToDouble(image.Height)) * Convert.ToDouble(image.Width));
                    //設定修改後的圖寬  
                    fixHeight = maxPx;

                }



            }
            else
            {//圖片沒有超過設定值,不執行縮圖  

                fixHeight = image.Height;

                fixWidth = image.Width;

            }

            int[] fixWidthAndfixHeight = { fixWidth, fixHeight };



            return fixWidthAndfixHeight;
        }


        /// <summary>
        /// 寬度維持maxWidth,高度等比例縮放   - 計算方法
        /// </summary>
        /// <param name="image"></param>
        /// <param name="maxWidth"></param>
        /// <returns></returns>
        public static int[] GetThumbPic_Width(System.Drawing.Image image, int maxWidth)
        {
            //要回傳的結果
            int fixWidth = 0;
            int fixHeight = 0;

            if (image.Width > maxWidth)
            //如果圖片的寬大於最大值 
            {


                //等比例的圖高
                fixHeight = Convert.ToInt32((Convert.ToDouble(maxWidth) / Convert.ToDouble(image.Width)) * Convert.ToDouble(image.Height));
                //設定修改後的圖寬  
                fixWidth = maxWidth;

            }
            else
            {//圖片寬沒有超過設定值,不執行縮圖  

                fixHeight = image.Height;

                fixWidth = image.Width;

            }

            int[] fixWidthAndfixHeight = { fixWidth, fixHeight };



            return fixWidthAndfixHeight;


        }

        /// <summary>
        /// 高度維持maxHeight,寬度等比例縮放  - 計算方法
        /// </summary>
        /// <param name="image"></param>
        /// <param name="maxHeight"></param>
        /// <returns></returns>
        public static int[] GetThumbPic_Height(System.Drawing.Image image, int maxHeight)
        {
            //要回傳的值
            int fixWidth = 0;
            int fixHeight = 0;

            if (image.Height > maxHeight)
            //如果圖片的高大於最大值 
            {
                //等比例的寬
                fixWidth = Convert.ToInt32((Convert.ToDouble(maxHeight) / Convert.ToDouble(image.Height)) * Convert.ToDouble(image.Width));
                //圖高固定  
                fixHeight = maxHeight;

            }
            else
            {//圖片的高沒有超過設定值 

                fixHeight = image.Height;

                fixWidth = image.Width;

            }

            int[] fixWidthAndfixHeight = { fixWidth, fixHeight };



            return fixWidthAndfixHeight;
        }
        #endregion

        #region 產生縮圖並儲存
        /// <summary>
        /// 產生縮圖並儲存 寬高誰較長就縮誰
        /// </summary>
        /// <param name="srcImagePath">來源圖片的路徑</param>
        /// <param name="maxPix">超過多少像素就要等比例縮圖</param>
        /// <param name="saveThumbFilePath">縮圖的儲存檔案路徑</param>
        public static void SaveThumbPic(string srcImagePath, int maxPix, string saveThumbFilePath)
        {
            //為了callBack而callBack的寫法
            System.Drawing.Image.GetThumbnailImageAbort callBack =
                 new System.Drawing.Image.GetThumbnailImageAbort(() => { return false; });

            //讀取原始圖片
            using (FileStream fs = new FileStream(srcImagePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
            {

                System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(fs);
                //取得原始圖片
                System.Drawing.Image image = bitmap;
                // 計算維持比例的縮圖大小
                //int[] thumbnailScaleWidth = GetThumbPic_Width(image, maxPix);
                //int[] thumbnailScaleHeight = GetThumbPic_Height(image, maxPix);
                int[] thumbailScale = GetThumbPic_WidthAndHeight(image, maxPix);

                //寬高誰較長就縮誰
                // 產生縮圖
                System.Drawing.Image smallImage =
                image.GetThumbnailImage(thumbailScale[0], thumbailScale[1], callBack, IntPtr.Zero);
                // 將縮圖存檔
                smallImage.Save(saveThumbFilePath);

               

                

                // 釋放
                image.Dispose();

            }
        }

        /// <summary>
        /// 產生縮圖並儲存 寬度維持maxpix,高度等比例
        /// </summary>
        /// <param name="srcImagePath">來源圖片的路徑</param>
        /// <param name="maxPix">超過多少像素就要等比例縮圖</param>
        /// <param name="saveThumbFilePath">縮圖的儲存檔案路徑</param>
        public static void SaveThumbPicWidth(string srcImagePath, int maxPix, string saveThumbFilePath)
        {
            //為了callBack而callBack的寫法
            System.Drawing.Image.GetThumbnailImageAbort callBack =
                 new System.Drawing.Image.GetThumbnailImageAbort(() => { return false; });

            //讀取原始圖片
            using (FileStream fs = new FileStream(srcImagePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
            {

                System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(fs);
                //取得原始圖片
                System.Drawing.Image image = bitmap;
                // 計算維持比例的縮圖大小
                int[] thumbnailScaleWidth = GetThumbPic_Width(image, maxPix);



                //寬度維持maxpix,高度等比例
                // 產生縮圖
                System.Drawing.Image smallImage =
                image.GetThumbnailImage(thumbnailScaleWidth[0], thumbnailScaleWidth[1], callBack, IntPtr.Zero);
                // 將縮圖存檔
                smallImage.Save(saveThumbFilePath);





                // 釋放
                image.Dispose();

            }
        }

        /// <summary>
        /// 產生縮圖並儲存 高度維持maxPix,寬度等比例
        /// </summary>
        /// <param name="srcImagePath">來源圖片的路徑</param>
        /// <param name="maxPix">超過多少像素就要等比例縮圖</param>
        /// <param name="saveThumbFilePath">縮圖的儲存檔案路徑</param>
        public static void SaveThumbPicHeight(string srcImagePath, int maxPix, string saveThumbFilePath)
        {
            //為了callBack而callBack的寫法
            System.Drawing.Image.GetThumbnailImageAbort callBack =
                 new System.Drawing.Image.GetThumbnailImageAbort(() => { return false; });

            //讀取原始圖片
            using (FileStream fs = new FileStream(srcImagePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
            {

                System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(fs);
                //取得原始圖片
                System.Drawing.Image image = bitmap;
                // 計算維持比例的縮圖大小
                
                int[] thumbnailScaleHeight = GetThumbPic_Height(image, maxPix);


                //高度維持maxPix,寬度等比例
                // 產生縮圖
                System.Drawing.Image smallImage =
                image.GetThumbnailImage(thumbnailScaleHeight[0], thumbnailScaleHeight[1], callBack, IntPtr.Zero);
                // 將縮圖存檔
                smallImage.Save(saveThumbFilePath);





                // 釋放
                image.Dispose();

            }
        }
        
        #endregion
    }
}

 

 

2013.10.21更新後的演算法


using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        //使用方法
        static void Main(string[] args)
        {
            string path = @"D:\source.jpg";
            SaveThumbPicWidth(path, 220, @"D:\width.jpg");
            SaveThumbPicHeight(path, 220, @"D:\height.jpg");
            SaveThumbPic(path, 220, @"D:\unknown.jpg");
        }


        #region  取得圖片等比例縮圖後的寬和高像素
        /// <summary>
        ///  寬高誰較長就縮誰  - 計算方法
        /// </summary>
        /// <param name="image">System.Drawing.Image 的物件</param>
        /// <param name="maxPx">寬或高超過多少像素就要縮圖</param>
        /// <returns>回傳int陣列,索引0為縮圖後的寬度、索引1為縮圖後的高度</returns>
        public static int[] GetThumbPic_WidthAndHeight(System.Drawing.Image image, int maxPx)
        {

            int fixWidth = 0;

            int fixHeight = 0;

            if (image.Width > maxPx || image.Height > maxPx)
            //如果圖片的寬大於最大值或高大於最大值就往下執行  
            {

                if (image.Width >= image.Height)
                //圖片的寬大於圖片的高  
                {

                    fixHeight = Convert.ToInt32((Convert.ToDouble(maxPx) / Convert.ToDouble(image.Width)) * Convert.ToDouble(image.Height));
                    //設定修改後的圖高  
                    fixWidth = maxPx;
                }
                else
                {

                    fixWidth = Convert.ToInt32((Convert.ToDouble(maxPx) / Convert.ToDouble(image.Height)) * Convert.ToDouble(image.Width));
                    //設定修改後的圖寬  
                    fixHeight = maxPx;

                }



            }
            else
            {//圖片沒有超過設定值,不執行縮圖  

                fixHeight = image.Height;

                fixWidth = image.Width;

            }

            int[] fixWidthAndfixHeight = { fixWidth, fixHeight };



            return fixWidthAndfixHeight;
        }


        /// <summary>
        /// 寬度維持maxWidth,高度等比例縮放   - 計算方法
        /// </summary>
        /// <param name="image"></param>
        /// <param name="maxWidth"></param>
        /// <returns></returns>
        public static int[] GetThumbPic_Width(System.Drawing.Image image, int maxWidth)
        {
            //要回傳的結果
            int fixWidth = 0;
            int fixHeight = 0;

            if (image.Width > maxWidth)
            //如果圖片的寬大於最大值 
            {


                //等比例的圖高
                fixHeight = Convert.ToInt32((Convert.ToDouble(maxWidth) / Convert.ToDouble(image.Width)) * Convert.ToDouble(image.Height));
                //設定修改後的圖寬  
                fixWidth = maxWidth;

            }
            else
            {//圖片寬沒有超過設定值,不執行縮圖  

                fixHeight = image.Height;

                fixWidth = image.Width;

            }

            int[] fixWidthAndfixHeight = { fixWidth, fixHeight };



            return fixWidthAndfixHeight;


        }

        /// <summary>
        /// 高度維持maxHeight,寬度等比例縮放  - 計算方法
        /// </summary>
        /// <param name="image"></param>
        /// <param name="maxHeight"></param>
        /// <returns></returns>
        public static int[] GetThumbPic_Height(System.Drawing.Image image, int maxHeight)
        {
            //要回傳的值
            int fixWidth = 0;
            int fixHeight = 0;

            if (image.Height > maxHeight)
            //如果圖片的高大於最大值 
            {
                //等比例的寬
                fixWidth = Convert.ToInt32((Convert.ToDouble(maxHeight) / Convert.ToDouble(image.Height)) * Convert.ToDouble(image.Width));
                //圖高固定  
                fixHeight = maxHeight;

            }
            else
            {//圖片的高沒有超過設定值 

                fixHeight = image.Height;

                fixWidth = image.Width;

            }

            int[] fixWidthAndfixHeight = { fixWidth, fixHeight };



            return fixWidthAndfixHeight;
        }
        #endregion

        #region 產生縮圖並儲存
        /// <summary>
        /// 產生縮圖並儲存 寬高誰較長就縮誰
        /// </summary>
        /// <param name="srcImagePath">來源圖片的路徑</param>
        /// <param name="maxPix">超過多少像素就要等比例縮圖</param>
        /// <param name="saveThumbFilePath">縮圖的儲存檔案路徑</param>
        public static void SaveThumbPic(string srcImagePath, int maxPix, string saveThumbFilePath)
        {
            //讀取原始圖片 
            using (FileStream fs = new FileStream(srcImagePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                //取得原始圖片 
                System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(fs);

                //圖片寬高
                int ImgWidth = bitmap.Width;
                int ImgHeight = bitmap.Height;
                // 計算維持比例的縮圖大小 
                int[] thumbnailScaleWidth = GetThumbPic_WidthAndHeight(bitmap, maxPix);
                int AfterImgWidth = thumbnailScaleWidth[0];
                int AfterImgHeight = thumbnailScaleWidth[1];

                // 產生縮圖 
                using (var bmp = new Bitmap(AfterImgWidth, AfterImgHeight))
                {
                    using (var gr = Graphics.FromImage(bmp))
                    {

                        gr.CompositingQuality = CompositingQuality.HighQuality;
                        gr.SmoothingMode = SmoothingMode.HighQuality;
                        gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
                        gr.DrawImage(bitmap, new Rectangle(0, 0, AfterImgWidth, AfterImgHeight), 0, 0, ImgWidth, ImgHeight, GraphicsUnit.Pixel);
                        bmp.Save(saveThumbFilePath);
                    }
                }



            }
        }

        /// <summary>
        /// 產生縮圖並儲存 寬度維持maxpix,高度等比例
        /// </summary>
        /// <param name="srcImagePath">來源圖片的路徑</param>
        /// <param name="widthMaxPix">超過多少像素就要等比例縮圖</param>
        /// <param name="saveThumbFilePath">縮圖的儲存檔案路徑</param>
        public static void SaveThumbPicWidth(string srcImagePath, int widthMaxPix, string saveThumbFilePath)
        {
            //讀取原始圖片 
            using (FileStream fs = new FileStream(srcImagePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                //取得原始圖片 
                System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(fs);

                //圖片寬高
                int ImgWidth = bitmap.Width;
                int ImgHeight = bitmap.Height;
                // 計算維持比例的縮圖大小 
                int[] thumbnailScaleWidth = GetThumbPic_Width(bitmap, widthMaxPix);
                int AfterImgWidth = thumbnailScaleWidth[0];
                int AfterImgHeight = thumbnailScaleWidth[1];

                // 產生縮圖 
                using (var bmp = new Bitmap(AfterImgWidth, AfterImgHeight))
                {
                    using (var gr = Graphics.FromImage(bmp))
                    {

                        gr.CompositingQuality = CompositingQuality.HighQuality;
                        gr.SmoothingMode = SmoothingMode.HighQuality;
                        gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
                        gr.DrawImage(bitmap, new Rectangle(0, 0, AfterImgWidth, AfterImgHeight), 0, 0, ImgWidth, ImgHeight, GraphicsUnit.Pixel);
                        bmp.Save(saveThumbFilePath);
                    }
                }



            }
        }

        /// <summary>
        /// 產生縮圖並儲存 高度維持maxPix,寬度等比例
        /// </summary>
        /// <param name="srcImagePath">來源圖片的路徑</param>
        /// <param name="heightMaxPix">超過多少像素就要等比例縮圖</param>
        /// <param name="saveThumbFilePath">縮圖的儲存檔案路徑</param>
        public static void SaveThumbPicHeight(string srcImagePath, int heightMaxPix, string saveThumbFilePath)
        {
            //讀取原始圖片 
            using (FileStream fs = new FileStream(srcImagePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                //取得原始圖片 
                System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(fs);

                //圖片寬高
                int ImgWidth = bitmap.Width;
                int ImgHeight = bitmap.Height;
                // 計算維持比例的縮圖大小 
                int[] thumbnailScaleWidth = GetThumbPic_Height(bitmap, heightMaxPix);
                int AfterImgWidth = thumbnailScaleWidth[0];
                int AfterImgHeight = thumbnailScaleWidth[1];

                // 產生縮圖 
                using (var bmp = new Bitmap(AfterImgWidth, AfterImgHeight))
                {
                    using (var gr = Graphics.FromImage(bmp))
                    {

                        gr.CompositingQuality = CompositingQuality.HighQuality;
                        gr.SmoothingMode = SmoothingMode.HighQuality;
                        gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
                        gr.DrawImage(bitmap, new Rectangle(0, 0, AfterImgWidth, AfterImgHeight), 0, 0, ImgWidth, ImgHeight, GraphicsUnit.Pixel);
                        bmp.Save(saveThumbFilePath);
                    }
                }



            }
        }

        #endregion
    }
}

2017.10.16 更新

2013.10.21演算法的Graphics要設定太多成員,有點囉嗦

以下使用

Bitmap bmpThumb = new Bitmap(bmpOld, newWidth, newHeight);

↑一行程式碼來產生縮圖(從恆逸資訊上課學來的XD)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

/*引用命名空間*/
using System.Drawing;
using System.IO;

namespace ConsoleApp1TestThumb
{
    class Program
    {
        //使用方法
        static void Main(string[] args)
        {
            const int maxPx = 1024;
            string path = @"D:\source.jpg";
            SaveThumbPicWidth(path, maxPx, @"D:\width.jpg");
            SaveThumbPicHeight(path, maxPx, @"D:\height.jpg");
            SaveThumbPic(path, maxPx, @"D:\unknown.jpg");
        }


        #region  取得圖片等比例縮圖後的寬和高像素
        /// <summary>
        ///  寬高誰較長就縮誰  - 計算方法
        /// </summary>
        /// <param name="bmp">System.Drawing.Image 的物件</param>
        /// <param name="maxPx">寬或高超過多少像素就要縮圖</param>
        /// <returns>回傳int陣列,索引0為縮圖後的寬度、索引1為縮圖後的高度</returns>
        public static int[] GetThumbPic_WidthAndHeight(Bitmap bmp, int maxPx)
        {

            int newWidth = 0; 
            int newHeight = 0;

            if (bmp.Width > maxPx || bmp.Height > maxPx)
            //如果圖片的寬大於最大值或高大於最大值就往下執行  
            {

                if (bmp.Width >= bmp.Height)
                //圖片的寬大於圖片的高  
                {

                    newHeight = Convert.ToInt32((Convert.ToDouble(maxPx) / Convert.ToDouble(bmp.Width)) * Convert.ToDouble(bmp.Height));
                    //設定修改後的圖高  
                    newWidth = maxPx;
                }
                else
                {

                    newWidth = Convert.ToInt32((Convert.ToDouble(maxPx) / Convert.ToDouble(bmp.Height)) * Convert.ToDouble(bmp.Width));
                    //設定修改後的圖寬  
                    newHeight = maxPx; 
                } 
            }
            else
            {//圖片沒有超過設定值,不執行縮圖   
                newHeight = bmp.Height; 
                newWidth = bmp.Width; 
            }

            int[] newWidthAndfixHeight = { newWidth, newHeight };
             
            return newWidthAndfixHeight;
        }


        /// <summary>
        /// 寬度維持maxWidth,高度等比例縮放   - 計算方法
        /// </summary>
        /// <param name="image"></param>
        /// <param name="maxWidth"></param>
        /// <returns></returns>
        public static int[] GetThumbPic_Width(Bitmap bmp, int maxWidth)
        {
            //要回傳的結果
            int newWidth = 0;
            int newHeight = 0;

            if (bmp.Width > maxWidth)
            //如果圖片的寬大於最大值 
            {
                 
                //等比例的圖高
                newHeight = Convert.ToInt32((Convert.ToDouble(maxWidth) / Convert.ToDouble(bmp.Width)) * Convert.ToDouble(bmp.Height));
                //設定修改後的圖寬  
                newWidth = maxWidth;

            }
            else
            {//圖片寬沒有超過設定值,不執行縮圖  

                newHeight = bmp.Height; 
                newWidth = bmp.Width; 
            }

            int[] newWidthAndfixHeight = { newWidth, newHeight };



            return newWidthAndfixHeight;


        }

        /// <summary>
        /// 高度維持maxHeight,寬度等比例縮放  - 計算方法
        /// </summary>
        /// <param name="bmp"></param>
        /// <param name="maxHeight"></param>
        /// <returns></returns>
        public static int[] GetThumbPic_Height(Bitmap bmp, int maxHeight)
        {
            //要回傳的值
            int newWidth = 0;
            int newHeight = 0;

            if (bmp.Height > maxHeight)
            //如果圖片的高大於最大值 
            {
                //等比例的寬
                newWidth = Convert.ToInt32((Convert.ToDouble(maxHeight) / Convert.ToDouble(bmp.Height)) * Convert.ToDouble(bmp.Width));
                //圖高固定  
                newHeight = maxHeight;

            }
            else
            {//圖片的高沒有超過設定值 

                newHeight = bmp.Height; 
                newWidth = bmp.Width; 
            }

            int[] newWidthAndfixHeight = { newWidth, newHeight };
             
            return newWidthAndfixHeight;
        }
        #endregion

        #region 產生縮圖並儲存
        /// <summary>
        /// 產生縮圖並儲存 寬高誰較長就縮誰
        /// </summary>
        /// <param name="srcImagePath">來源圖片的路徑</param>
        /// <param name="maxPix">超過多少像素就要等比例縮圖</param>
        /// <param name="saveThumbFilePath">縮圖的儲存檔案路徑</param>
        public static void SaveThumbPic(string srcImagePath, int maxPix, string saveThumbFilePath)
        {
            //讀取原始圖片 
            using (FileStream fs = new FileStream(srcImagePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                //取得原始圖片 
                  Bitmap bmpOld = new  Bitmap(fs);
                 
                // 計算維持比例的縮圖大小 
                int[] thumbnailScaleWidth = GetThumbPic_WidthAndHeight(bmpOld, maxPix);
                int newWidth = thumbnailScaleWidth[0];
                int newHeight = thumbnailScaleWidth[1];

                // 產生縮圖 
                Bitmap bmpThumb = new Bitmap(bmpOld, newWidth, newHeight);
                       bmpThumb.Save(saveThumbFilePath);
                    
            }//end using 
        }

        /// <summary>
        /// 產生縮圖並儲存 寬度維持maxpix,高度等比例
        /// </summary>
        /// <param name="srcImagePath">來源圖片的路徑</param>
        /// <param name="widthMaxPix">超過多少像素就要等比例縮圖</param>
        /// <param name="saveThumbFilePath">縮圖的儲存檔案路徑</param>
        public static void SaveThumbPicWidth(string srcImagePath, int widthMaxPix, string saveThumbFilePath)
        {
            //讀取原始圖片 
            using (FileStream fs = new FileStream(srcImagePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                //取得原始圖片 
                 Bitmap bmpOld = new Bitmap(fs);

                //圖片寬高 
                // 計算維持比例的縮圖大小 
                int[] thumbnailScaleWidth = GetThumbPic_Width(bmpOld, widthMaxPix);
                int newWidth = thumbnailScaleWidth[0];
                int newHeight = thumbnailScaleWidth[1];

                // 產生縮圖 
                Bitmap bmpThumb = new Bitmap(bmpOld, newWidth, newHeight);
                bmpThumb.Save(saveThumbFilePath);
                    
            }//end using
        }

        /// <summary>
        /// 產生縮圖並儲存 高度維持maxPix,寬度等比例
        /// </summary>
        /// <param name="srcImagePath">來源圖片的路徑</param>
        /// <param name="heightMaxPix">超過多少像素就要等比例縮圖</param>
        /// <param name="saveThumbFilePath">縮圖的儲存檔案路徑</param>
        public static void SaveThumbPicHeight(string srcImagePath, int heightMaxPix, string saveThumbFilePath)
        {
            //讀取原始圖片 
            using (FileStream fs = new FileStream(srcImagePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                //取得原始圖片 
                 Bitmap bmpOld = new  Bitmap(fs);

                
                // 計算維持比例的縮圖大小 
                int[] thumbnailScaleWidth = GetThumbPic_Height(bmpOld, heightMaxPix);
                int newWidth = thumbnailScaleWidth[0];
                int newHeight = thumbnailScaleWidth[1];

                // 產生縮圖 
                Bitmap bmpThumb = new Bitmap(bmpOld, newWidth, newHeight);
                       bmpThumb.Save(saveThumbFilePath);
                   
            }//end using 
        }

        #endregion
    }
}

經測試,不管是2017.10.16寫法或是2013.10.21寫法,產生出來的縮圖雖然不像第一種寫法那麼誇張破壞壓縮,但多少還是會失真一些些顏色

哪天想到解法再補充…