網站需對用戶上傳圖片自動添加版權聲明、水印或品牌標識。使用 System.Drawing 命名空間的 Graphics 類別,可在伺服器端無需 Photoshop 即時合成,支援文字、圖片疊加、透明度、旋轉等效果。
// 目標尺寸同原圖或自訂
Bitmap bitmap = new Bitmap(pictureBox2.Width, pictureBox2.Height, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(bitmap);
g.Clear(Color.Transparent);
g.DrawImage(pictureBox1.Image, 0, 0);
g.DrawString(
textBox2.Text, // 版權文字
new Font("黑體", 15), // 字型與大小
new SolidBrush(Color.Red), // 紅色實體筆刷
new Rectangle(20, 20, 100, 100) // 繪製區域
);
pictureBox2.Image = bitmap;
bitmap.Save(@"c:\abc.bmp", ImageFormat.Bmp);
using (SolidBrush brush = new SolidBrush(Color.FromArgb(128, 255, 255, 255))) { // 50% 不透明度白色
g.DrawString("Copyright © 2024", font, brush, x, y);
}
Image logo = Image.FromFile("logo.png");
g.DrawImage(logo, new Rectangle(x, y, logo.Width, logo.Height));
for (int x = 0; x < bmp.Width; x += watermark.Width + 50)
for (int y = 0; y < bmp.Height; y += watermark.Height + 50)
g.DrawImage(watermark, x, y);
g.TranslateTransform(centerX, centerY);
g.RotateTransform(-45);
g.DrawString(text, font, brush, -textWidth/2, 0);
g.ResetTransform();
private void btnSelect_Click(object sender, EventArgs e) {
if (openFileDialog1.ShowDialog() == DialogResult.OK) {
string file = openFileDialog1.FileName;
if (string.IsNullOrEmpty(file)) {
MessageBox.Show("請選擇圖片");
return;
}
txtPath.Text = file;
using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read)) {
try {
pictureBox1.Image = Image.FromStream(fs);
} catch {
MessageBox.Show("無法識別的圖片格式");
}
}
}
}
public void AddWatermark(HttpPostedFile uploadFile, string outputPath, string watermarkText) {
using (Image src = Image.FromStream(uploadFile.InputStream))
using (Bitmap bmp = new Bitmap(src.Width, src.Height, PixelFormat.Format32bppArgb))
using (Graphics g = Graphics.FromImage(bmp)) {
g.DrawImage(src, 0, 0);
using (Font font = new Font("Arial", 20, FontStyle.Bold))
using (SolidBrush brush = new SolidBrush(Color.FromArgb(100, 255, 255, 255))) {
SizeF textSize = g.MeasureString(watermarkText, font);
float x = bmp.Width - textSize.Width - 20;
float y = bmp.Height - textSize.Height - 20;
g.DrawString(watermarkText, font, brush, x, y);
}
bmp.Save(outputPath, ImageFormat.Jpeg);
}
}
| 議題 | 說明 |
|---|---|
| GDI+ 物件釋放 | 所有 Image、Graphics、Font、Brush、Pen 必須 Dispose 或 using |
| 字型可用性 | 伺服器需安裝指定字型,否則回退預設字型導致版面錯亂 |
| 大圖記憶體 | 超大圖片可能造成 OOM,考慮分塊處理或限制上傳尺寸 |
| 格式保真 | JPEG 儲存會損失品質,PNG 支援無損與透明 |
| 執行緒安全 | System.Drawing 非執行緒安全,高併發需鎖定或佇列處理 |
GDI+ 提供直觀的圖形合成 API,幾行代碼即可實現圖片版權保護。掌握 Graphics 座標系、筆刷/筆型別、Alpha 混合、資源釋放模式是核心技能。生產系統建議遷移至 ImageSharp 等現代庫以獲得跨平台支援與更佳記憶體安全性。