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

C# 縮略圖模糊問題解決:棄用 GetThumbnailImage 改用 Graphics.DrawImage 高質量繪製

     編輯:關於C#

問題現象

使用 Image.GetThumbnailImage() 將 300×300 PNG 縮放為 48×48 時,輸出圖片明顯模糊、鋸齒嚴重,品質無法接受。

原因分析

GetThumbnailImage 內部使用預設低質量插值演算法,且不提供參數控制繪圖品質(插值模式、平滑模式、像素偏移、合成品質等),適合快速預覽,不適合生產級縮略圖產出。

解決方案:Graphics.DrawImage + 高品質參數

private void SaveThumbnail(Bitmap originBitmap, int width, int height, 
    string directory, string filename, string extension)
{
    var physicalPath = Path.Combine(directory, filename + extension);
    
    using (var newImage = new Bitmap(width, height))
    using (var graphic = GetHighQualityGraphics(originBitmap, newImage))
    {
        // 核心:高品質繪製
        graphic.DrawImage(originBitmap, 0, 0, width, height);
        
        // 儲存時指定最高品質編碼
        using (var encoderParams = new EncoderParameters(1))
        {
            encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
            var codec = ImageCodecInfo.GetImageEncoders()
                .FirstOrDefault(x => x.FilenameExtension.Contains(extension.ToUpperInvariant()));
            newImage.Save(physicalPath, codec, encoderParams);
        }
    }
}

private Graphics GetHighQualityGraphics(Image source, Bitmap target)
{
    // 保持原圖解析度(DPI),避免尺寸誤差
    target.SetResolution(source.HorizontalResolution, source.VerticalResolution);
    
    var g = Graphics.FromImage(target);
    g.InterpolationMode = InterpolationMode.HighQualityBicubic; // 雙三次插值,縮放最佳
    g.SmoothingMode = SmoothingMode.HighQuality;                // 邊緣平滑
    g.PixelOffsetMode = PixelOffsetMode.HighQuality;            // 像素偏移修正
    g.CompositingQuality = CompositingQuality.HighQuality;      // 合成品質
    return g;
}

關鍵參數說明

屬性推薦值作用
InterpolationModeHighQualityBicubic雙三次插值,縮放平滑度最高
SmoothingModeHighQuality反鋸齒、邊緣平滑
PixelOffsetModeHighQuality像素渲染位置修正,減少偏移伪影
CompositingQualityHighQuality混合/合成運算精度
SetResolution同源圖 DPI確保物理尺寸一致,避免列印/顯示異常

效果對比

修改後輸出的 48×48 縮略圖邊緣銳利、色彩過渡自然、細節保留度高,完全滿足生產環境品質要求。

補充建議

  • 若需支援透明背景(PNG),確保 new Bitmap 使用 PixelFormat.Format32bppArgb
  • 大量批次處理時,考慮重用 EncoderParameters 與 ImageCodecInfo 物件減少 GC 壓力
  • .NET 6+ 可嘗試 ImageSharp、SkiaSharp 等跨平台高效能圖像庫
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved