首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

C# 產生圖片縮圖的兩種核心實作策略完解

     編輯:ASP.NET 基礎

前言

縮圖生成是影像處理常見需求。.NET System.Drawing 命名空間提供兩種主要路徑:手動繪圖控制(Graphics.DrawImage)與 內建 GetThumbnailImage。前者靈活支援裁切、比例縮放、高品質插值;後者程式碼極簡但品質與參數控制有限。本文深度解析兩種策略的完整實作、優缺點比較與選型指南。

策略一:Graphics 手動繪圖——完全掌控品質與幾何

核心步驟:

  1. 載入原圖 Image.FromFile。
  2. 依模式計算目標寬高與繪圖來源矩形(裁切座標)。
  3. 建立 Bitmap 畫布與 Graphics 物件。
  4. 設定高品質插值 InterpolationMode.HighQualityBicubic、平滑模式 SmoothingMode.HighQuality。
  5. 呼叫 DrawImage 繪製指定區域。
  6. 依需求儲存為 JPEG/PNG/GIF/BMP。

支援四種縮放模式

  • HW:強制指定寬高,可能變形。
  • W:指定寬度,高度等比縮放。
  • H:指定高度,寬度等比縮放。
  • Cut:指定寬高並置中裁切,保持比例不變形(適合縮圖牆)。

完整實作程式碼

public static void MakeThumbnail(
    string sourcePath, string destPath,
    int width, int height, string mode, string format = "jpg")
{
    using (Image original = Image.FromFile(sourcePath))
    {
        int ow = original.Width, oh = original.Height;
        int targetW = width, targetH = height;
        int x = 0, y = 0, srcW = ow, srcH = oh;

        switch (mode.ToUpper())
        {
            case "W":
                targetH = oh * width / ow;
                break;
            case "H":
                targetW = ow * height / oh;
                break;
            case "CUT":
                double targetRatio = (double)width / height;
                double sourceRatio = (double)ow / oh;
                if (sourceRatio > targetRatio)
                {
                    srcH = oh;
                    srcW = (int)(oh * targetRatio);
                    x = (ow - srcW) / 2;
                }
                else
                {
                    srcW = ow;
                    srcH = (int)(ow / targetRatio);
                    y = (oh - srcH) / 2;
                }
                break;
        }

        using (Bitmap bmp = new Bitmap(targetW, targetH))
        using (Graphics g = Graphics.FromImage(bmp))
        {
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.Clear(Color.Transparent);
            g.DrawImage(original,
                new Rectangle(0, 0, targetW, targetH),
                new Rectangle(x, y, srcW, srcH),
                GraphicsUnit.Pixel);

            ImageFormat imgFormat = format.ToLower() switch
            {
                "png" => ImageFormat.Png,
                "gif" => ImageFormat.Gif,
                "bmp" => ImageFormat.Bmp,
                _ => ImageFormat.Jpeg
            };
            bmp.Save(destPath, imgFormat);
        }
    }
}

策略二:Image.GetThumbnailImage——極速原型開發

.NET Framework 內建方法,一行程式碼即可產生縮圖,但有已知限制:

  • 內部使用低品質演算法,邊緣鋸齒明顯。
  • 不支援裁切模式,僅等比縮放。
  • 需提供 Image.GetThumbnailImageAbort 回呼(通常傳回 false 即可)。

封裝類別範例(四種多載)


public class ThumbnailHelper
{
    private readonly Image _source;

    public ThumbnailHelper(string filePath) => _source = Image.FromFile(filePath);

    // 1. 回傳 Image 物件(指定寬高)
    public Image GetThumbnail(int w, int h)
    {
        return _source.GetThumbnailImage(w, h, () => false, IntPtr.Zero);
    }

    // 2. 直接儲存檔案(指定寬高)
    public bool SaveThumbnail(int w, int h, string destPath)
    {
        try
        {
            using (var thumb = GetThumbnail(w, h))
            {
                thumb.Save(destPath, ImageFormat.Jpeg);
            }
            return true;
        }
        catch { return false; }
    }

    // 3. 依比例縮放(0.0~1.0)
    public Image GetThumbnail(double scale)
    {
        int w = (int)(_source.Width * scale);
        int h = (int)(_source.Height * scale);
        return GetThumbnail(w, h);
    }

    // 4. 依比例縮放並儲存
    public bool SaveThumbnail(double scale, string destPath)
    {
        try
        {
            using (var thumb = GetThumbnail(scale))
            {
                thumb.Save(destPath, ImageFormat.Jpeg);
            }
            return true;
        }
        catch { return false; }
    }

    public void Dispose() => _source?.Dispose();
}

策略比較與選型建議

維度Graphics 手動繪圖GetThumbnailImage
圖片品質⭐⭐⭐⭐⭐ (可調插值演算法)⭐⭐ (固定低品質)
功能彈性支援裁切、旋轉、水印、多格式僅等比縮放
程式碼複雜度中等 (~50 行)極低 (~5 行)
效能稍慢(高品質插值計算量大)極快(原生最佳化)
適用場景正式產品、使用者頭像、商品縮圖牆快速原型、後台預覽、臨時縮圖

進階補充:.NET 6+ / 跨平台考量

System.Drawing.Common 在非 Windows 平台僅支援基本功能,生產環境建議改用 ImageSharp 或 SkiaSharp:


// ImageSharp 範例
using (var img = Image.Load(sourcePath))
{
    img.Mutate(x => x.Resize(new ResizeOptions
    {
        Mode = ResizeMode.Crop, // 對應 Cut 模式
        Size = new Size(width, height)
    }));
    img.Save(destPath);
}

兩者皆為純 managed 程式碼,支援 Linux Docker 容器部署,且 API 更現代化。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved