使用 Image.GetThumbnailImage() 將 300×300 PNG 縮放為 48×48 時,輸出圖片明顯模糊、鋸齒嚴重,品質無法接受。
GetThumbnailImage 內部使用預設低質量插值演算法,且不提供參數控制繪圖品質(插值模式、平滑模式、像素偏移、合成品質等),適合快速預覽,不適合生產級縮略圖產出。
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;
}
| 屬性 | 推薦值 | 作用 |
|---|---|---|
| InterpolationMode | HighQualityBicubic | 雙三次插值,縮放平滑度最高 |
| SmoothingMode | HighQuality | 反鋸齒、邊緣平滑 |
| PixelOffsetMode | HighQuality | 像素渲染位置修正,減少偏移伪影 |
| CompositingQuality | HighQuality | 混合/合成運算精度 |
| SetResolution | 同源圖 DPI | 確保物理尺寸一致,避免列印/顯示異常 |
修改後輸出的 48×48 縮略圖邊緣銳利、色彩過渡自然、細節保留度高,完全滿足生產環境品質要求。
new Bitmap 使用 PixelFormat.Format32bppArgbEncoderParameters 與 ImageCodecInfo 物件減少 GC 壓力ImageSharp、SkiaSharp 等跨平台高效能圖像庫