早期 ASP.NET 需借助第三方元件產生縮圖,.NET Framework 內建 System.Drawing 命名空間已提供完整功能。本文提供一個可直接在 Web 應用使用的縮圖類別,支援常見圖片格式、等比例縮放、品質控制與編碼器選擇。
using System;
using System.Collections;
using System.Drawing;
using System.Drawing.Imaging;
using System.Web;
namespace Exam_C
{
public class ThumbnailMaker
{
private static readonly Hashtable MimeMap = new Hashtable
{
{".jpe", "image/jpeg"}, {".jpeg", "image/jpeg"}, {".jpg", "image/jpeg"},
{".png", "image/png"}, {".tif", "image/tiff"}, {".tiff", "image/tiff"},
{".bmp", "image/bmp"}
};
private const string AllowExt = ".jpe|.jpeg|.jpg|.png|.tif|.tiff|.bmp";
// 取得指定 MIME 類型的編碼器
private static ImageCodecInfo GetEncoder(string mimeType)
{
foreach (ImageCodecInfo ici in ImageCodecInfo.GetImageEncoders())
if (ici.MimeType == mimeType) return ici;
return null;
}
// 驗證副檔名
private static bool IsValidExt(string ext)
{
foreach (string e in AllowExt.Split('|'))
if (e.Equals(ext, StringComparison.OrdinalIgnoreCase)) return true;
return false;
}
// 儲存圖片並設定品質
private static void SaveImage(Image img, string path, ImageCodecInfo encoder)
{
EncoderParameters ep = new EncoderParameters(1);
ep.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
img.Save(path, encoder, ep);
ep.Dispose();
}
///
/// 產生縮圖
///
/// 來源圖片相對路徑
/// 縮圖儲存相對路徑,null 覆蓋原檔
/// 縮圖寬度(高度等比自動計算)
public static void CreateThumbnail(string srcPath, string destPath, int thumbWidth)
{
if (string.IsNullOrEmpty(srcPath)) throw new ArgumentNullException(nameof(srcPath));
string ext = System.IO.Path.GetExtension(srcPath).ToLower();
if (!IsValidExt(ext)) throw new ArgumentException($"不支援的格式,允許:{AllowExt}");
string physSrc = HttpContext.Current.Server.MapPath(srcPath);
using (Image srcImg = Image.FromFile(physSrc))
{
int srcW = srcImg.Width, srcH = srcImg.Height;
// 依長寬比決定縮圖高度
int thumbH = (srcW >= srcH * 1.3333) ? (srcH * thumbWidth / srcW) : (srcW * (thumbWidth * 3 / 4) / srcH);
if (thumbWidth < 1 || thumbH < 1) return;
using (Bitmap bmp = new Bitmap(thumbWidth, thumbH, PixelFormat.Format32bppArgb))
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.Transparent);
g.DrawImage(srcImg, new Rectangle(0, 0, thumbWidth, thumbH));
string savePath = string.IsNullOrEmpty(destPath) ? srcPath : destPath;
SaveImage(bmp, HttpContext.Current.Server.MapPath(savePath), GetEncoder((string)MimeMap[ext]));
}
}
}
}
}
// 在 Page_Load 或 Handler 中呼叫
ThumbnailMaker.CreateThumbnail("lionsky.jpg", "thumb_lionsky.jpg", 300);
Graphics.DrawImage 預設雙三次插值,效果優於單純拉伸。Encoder.Quality = 90 平衡檔案大小與視覺品質。using 確保 Image、Graphics、EncoderParameters 正確 Dispose。