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

C# 動態產生文字圖片完整解決方案:Watermark 類別實作

     編輯:關於C語言

需求背景

Web 應用常需動態產生帶有特殊字體、陰影、透明度、背景圖的文字圖片(如驗證碼、水印、標題圖)。利用 System.Drawing 命名空間下的 Bitmap、Graphics 即可完整實現。

功能清單

  • 自訂字體、大小、顏色、樣式(粗體/斜體)。
  • 支援文字陰影。
  • 可調整透明度 (Alpha 0-255)。
  • 背景:純色或指定圖片檔。
  • 自訂輸出圖片寬高、文字座標 (Left/Top)。
  • 自動縮放字體:文字過寬時遞減字號直到符合圖片寬度。
  • 輸出 JPEG,可調品質 (0-100)。

核心類別:Watermark

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

public class Watermark
{
    // 屬性(省略 getter/setter,僅列關鍵屬性)
    public int Width { get; set; } = 460;
    public int Height { get; set; } = 30;
    public string FontFamily { get; set; } = "華文行楷";
    public int FontSize { get; set; } = 20;
    public FontStyle FontStyle { get; set; } = FontStyle.Regular;
    public bool Adaptable { get; set; } = true;   // 自動縮放
    public bool Shadow { get; set; } = false;
    public string BackgroundImage { get; set; } = "";
    public Color BgColor { get; set; } = Color.FromArgb(255, 229, 229, 229);
    public int Left { get; set; } = 0;
    public int Top { get; set; } = 0;
    public int Alpha { get; set; } = 255;
    public int Red { get; set; } = 0;
    public int Green { get; set; } = 0;
    public int Blue { get; set; } = 0;
    public long Quality { get; set; } = 100;
    public string Text { get; set; } = "";
    public string ResultImage { get; set; } = "";

    public bool Create()
    {
        try
        {
            Bitmap bitmap;
            Graphics g;

            // 1. 建立畫布:純色或背景圖
            if (string.IsNullOrWhiteSpace(BackgroundImage))
            {
                bitmap = new Bitmap(Width, Height, PixelFormat.Format64bppArgb);
                g = Graphics.FromImage(bitmap);
                g.Clear(BgColor);
            }
            else
            {
                bitmap = new Bitmap(Image.FromFile(BackgroundImage));
                g = Graphics.FromImage(bitmap);
                // 實際寬高以背景圖為準
                Width = bitmap.Width;
                Height = bitmap.Height;
            }

            // 2. 高品質繪圖設定
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.CompositingQuality = CompositingQuality.HighQuality;

            // 3. 字體與自動縮放
            Font font = new Font(FontFamily, FontSize, FontStyle);
            SizeF textSize = g.MeasureString(Text, font);
            while (Adaptable && textSize.Width > bitmap.Width && FontSize > 1)
            {
                FontSize--;
                font = new Font(FontFamily, FontSize, FontStyle);
                textSize = g.MeasureString(Text, font);
            }

            // 4. 畫刷與格式
            Brush brush = new SolidBrush(Color.FromArgb(Alpha, Red, Green, Blue));
            StringFormat fmt = new StringFormat { Alignment = StringAlignment.Near };

            // 5. 陰影優先繪製
            if (Shadow)
            {
                Brush shadowBrush = new SolidBrush(Color.FromArgb(90, 0, 0, 0));
                g.DrawString(Text, font, shadowBrush, Left + 2, Top + 1);
            }

            // 6. 繪製主文字
            g.DrawString(Text, font, brush, new PointF(Left, Top), fmt);

            // 7. 儲存 JPEG
            var encoderParams = new EncoderParameters(1);
            encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, Quality);
            ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");
            bitmap.Save(ResultImage, jpegCodec, encoderParams);

            // 8. 釋放資源
            brush.Dispose();
            if (Shadow) ((IDisposable)g).Dispose(); // 陰影筆刷已在上方
            font.Dispose();
            g.Dispose();
            bitmap.Dispose();
            return true;
        }
        catch
        {
            return false;
        }
    }

    private static ImageCodecInfo GetEncoderInfo(string mimeType)
    {
        foreach (var codec in ImageCodecInfo.GetImageEncoders())
            if (codec.MimeType == mimeType) return codec;
        return null;
    }
}

使用範例

var wm = new Watermark
{
    Width = 600,
    Height = 100,
    Text = "動態產生文字圖片測試",
    FontFamily = "微軟正黑體",
    FontSize = 36,
    FontStyle = FontStyle.Bold,
    Red = 255, Green = 0, Blue = 0, Alpha = 200,
    Shadow = true,
    Left = 20, Top = 20,
    BgColor = Color.White,
    ResultImage = @"C:\Temp\watermark.jpg",
    Quality = 90
};
bool ok = wm.Create();
Console.WriteLine(ok ? "產生成功" : "產生失敗");

部署注意事項

  • 字體必須安裝於伺服器:FontFamily 指定的字體需存在於 Web 伺服器作業系統,否則會回退預設字體。
  • GDI+ 記憶體洩漏:務必 Dispose() 所有 Bitmap、Graphics、Font、Brush 物件,建議使用 using 區塊。
  • IIS 權限:應用程式集區身分需具備輸出目錄寫入權限。
  • .NET Core / 5+ Linux 容器:需安裝 libgdiplus 並啟用 System.Drawing.Common 相容性,或改用跨平台庫 ImageSharp、SkiaSharp。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved