本文整理三個高頻影像處理功能的 C# 實作:將大圖按網格切割、JPEG 品質壓縮、等比例產生縮圖。皆使用 System.Drawing 命名空間,支援自訂輸出品質,程式碼結構清晰,可直接整合至專案工具類別。
private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
foreach (var encoder in ImageCodecInfo.GetImageEncoders())
if (encoder.MimeType == mimeType) return encoder;
return null;
}
將來源影像按 X、Y 軸切割為 xNum × yNum 塊,每塊以指定 JPEG 品質儲存,檔名自動附加索引(如 output00.jpg、output01.jpg...)。
///
/// 圖片網格切割
///
/// 來源圖片完整路徑
/// X 軸切割數(欄數)
/// Y 軸切割數(列數)
/// JPEG 品質 0-100
/// 輸出檔名不含副檔名(將自動加索引與 .jpg)
/// 成功回傳 true
public static bool ImageCut(string sourceFile, int xNum, int yNum, long quality, string outputFile)
{
try
{
using (var src = new Bitmap(sourceFile))
{
var encoder = GetEncoderInfo("image/jpeg");
var encParams = new EncoderParameters(1);
encParams.Param[0] = new EncoderParameter(Encoder.Quality, quality);
float tileW = src.Width / (float)xNum;
float tileH = src.Height / (float)yNum;
for (int y = 0; y < yNum; y++)
{
for (int x = 0; x < xNum; x++)
{
var rect = new RectangleF(x * tileW, y * tileH, tileW, tileH);
using (var tile = src.Clone(rect, PixelFormat.Format24bppRgb))
{
string outPath = $"{outputFile}{x}{y}.jpg";
tile.Save(outPath, encoder, encParams);
}
}
}
}
return true;
}
catch { return false; }
}
應用場景: 大圖分塊上傳、地圖瓦片產生、拼圖遊戲素材準備。
保持原尺寸,僅調整 JPEG 壓縮品質以減小檔案大小。
///
/// 影像品質壓縮(不改變尺寸)
///
/// 來源圖片路徑
/// JPEG 品質 0-100
/// 輸出檔案路徑(建議 .jpg 副檔名)
/// 成功回傳 true
public static bool ImageCompress(string sourceFile, long quality, string outputFile)
{
try
{
using (var src = new Bitmap(sourceFile))
{
var encoder = GetEncoderInfo("image/jpeg");
var encParams = new EncoderParameters(1);
encParams.Param[0] = new EncoderParameter(Encoder.Quality, quality);
src.Save(outputFile, encoder, encParams);
}
return true;
}
catch { return false; }
}
品質建議值: 75-85 平衡檔案大小與視覺品質;90 以上肉眼幾乎無差異但檔案較大;60 以下明顯產生壓縮雜訊。
依指定倍數縮小影像(如 multiple=2 寬高各減半),搭配品質參數輸出。
///
/// 產生等比例縮圖
///
/// 來源圖片路徑
/// JPEG 品質 0-100
/// 縮小倍數(>1),如 2 表寬高各為原圖 1/2
/// 輸出檔案路徑
/// 成功回傳 true
public static bool GetThumImage(string sourceFile, long quality, int multiple, string outputFile)
{
try
{
using (var src = new Bitmap(sourceFile))
{
var encoder = GetEncoderInfo("image/jpeg");
var encParams = new EncoderParameters(1);
encParams.Param[0] = new EncoderParameter(Encoder.Quality, quality);
int newW = src.Width / multiple;
int newH = src.Height / multiple;
using (var thumb = new Bitmap(newW, newH))
using (var g = Graphics.FromImage(thumb))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic; // 高品質插值
g.DrawImage(src, 0, 0, newW, newH);
thumb.Save(outputFile, encoder, encParams);
}
}
return true;
}
catch { return false; }
}
關鍵設定: InterpolationMode.HighQualityBicubic 確保縮圖平滑無鋸齒;若需極速可用 Low 或 Default。
public static class ImageHelper
{
// 上述三個 public static 方法 + GetEncoderInfo 放在這裡
///
/// 批次處理範例:將資料夾下所有 JPG 壓縮品質 80 並產生 1/2 縮圖
///
public static void BatchProcess(string folderPath)
{
var files = Directory.GetFiles(folderPath, "*.jpg");
foreach (var f in files)
{
string compressed = Path.Combine(folderPath, "compressed", Path.GetFileName(f));
string thumb = Path.Combine(folderPath, "thumb", Path.GetFileName(f));
Directory.CreateDirectory(Path.GetDirectoryName(compressed));
Directory.CreateDirectory(Path.GetDirectoryName(thumb));
ImageCompress(f, 80, compressed);
GetThumImage(f, 80, 2, thumb);
}
}
}
Bitmap、Graphics、EncoderParameters 均以 using 區塊包裹,確保非受控資源及時釋放。try-catch 回傳 bool,正式專案建議拋出具體例外(FileNotFoundException、ArgumentException、ExternalException 等)供上層處理。System.Drawing.Common 僅在 Windows 完整支援;Linux/macOS 需安裝 libgdiplus 且功能受限。.NET 6+ 跨平台專案建議改用 ImageSharp、SkiaSharp 或 Pdfium。new Bitmap(path) 會載入完整像素至記憶體,易造成 OOM。可改用 ImageSharp 串流處理或分塊讀取。GetEncoderInfo 的 MIME Type 並調整 EncoderParameters(PNG 無品質參數,改用 Encoder.Compression)。| 操作 | 耗時 (ms) | 輸出大小 | 備註 |
|---|---|---|---|
| ImageCompress | ~120 | ~3.2MB | 純重新編碼 |
| GetThumImage (1/2) | ~80 | ~900KB | 含縮放繪製 |
| ImageCut (4×4) | ~350 | 16 檔共 ~3.5MB | 含 16 次 Clone+Save |