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

ASP.NET 使用 GDI+ 將文字繪製成圖片 (驗證碼/水印/簽名檔)

     編輯:關於ASP.NET

在 ASP.NET 中利用 System.Drawing (GDI+) 將文字渲染為圖片,常用於驗證碼、動態水印、個人化簽名檔、圖表標籤等場景。注意:System.Drawing 在 Linux/容器環境需安裝 libgdiplus,且非執行緒安全,高併發建議改用 ImageSharp、SkiaSharp 等跨平台庫。

核心實作類別


using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;

public class TextToImageRenderer
{
    /// 
    /// 將文字繪製成 JPEG 圖片
    /// 
    /// 要繪製的文字
    /// 輸出完整路徑
    /// 圖片寬度
    /// 圖片高度
    /// 字型名稱
    /// 字型大小
    /// 字型樣式
    /// 文字顏色
    /// 背景顏色
    /// 文字對齊
    public void CreateImage(
        string text, 
        string outputPath,
        int width = 400,
        int height = 200,
        string fontFamily = "Arial",
        float fontSize = 48,
        FontStyle fontStyle = FontStyle.Bold,
        Color? textColor = null,
        Color? backColor = null,
        StringAlignment textAlign = StringAlignment.Center)
    {
        using (Bitmap bitmap = new Bitmap(width, height))
        using (Graphics g = Graphics.FromImage(bitmap))
        {
            // 高品質設定
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;

            // 背景
            g.Clear(backColor ?? ColorTranslator.FromHtml("#f0f0f0"));

            // 字型與筆刷
            using (Font font = new Font(fontFamily, fontSize, fontStyle, GraphicsUnit.Pixel))
            using (SolidBrush brush = new SolidBrush(textColor ?? Color.Black))
            {
                // 版面區域
                RectangleF layoutRect = new RectangleF(0, 0, width, height);
                StringFormat format = new StringFormat
                {
                    Alignment = textAlign,
                    LineAlignment = StringAlignment.Center,
                    Trimming = StringTrimming.EllipsisCharacter
                };

                // 繪製文字
                g.DrawString(text, font, brush, layoutRect, format);
            }

            // 儲存 JPEG,品質 90%
            var encoderParams = new EncoderParameters(1);
            encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
            ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");
            bitmap.Save(outputPath, jpegCodec, encoderParams);
        }
    }

    private ImageCodecInfo GetEncoderInfo(string mimeType)
    {
        return ImageCodecInfo.GetImageEncoders()
            .FirstOrDefault(c => c.MimeType == mimeType);
    }
}

ASP.NET Web Forms / MVC 控制器直接輸出圖片串流 (不落地檔案)


public ActionResult GenerateTextImage(string text = "Hello")
{
    using (var bitmap = new Bitmap(300, 100))
    using (var g = Graphics.FromImage(bitmap))
    {
        g.Clear(Color.White);
        g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
        using (var font = new Font("Microsoft JhengHei", 24, FontStyle.Bold))
        using (var brush = new SolidBrush(Color.DarkBlue))
        {
            g.DrawString(text, font, brush, new PointF(10, 30));
        }

        using (var ms = new MemoryStream())
        {
            bitmap.Save(ms, ImageFormat.Png);
            return File(ms.ToArray(), "image/png");
        }
    }
}

前端直接使用:<img src="/Home/GenerateTextImage?text=Hello%20World" />

進階:驗證碼產生器 (含雜訊線、扭曲)


public class CaptchaGenerator
{
    private const string Chars = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
    private readonly Random _rng = new Random();

    public (string Code, byte[] ImageBytes) Generate(int length = 4, int width = 120, int height = 40)
    {
        string code = new string(Enumerable.Range(0, length).Select(_ => Chars[_rng.Next(Chars.Length)]).ToArray());
        
        using (var bmp = new Bitmap(width, height))
        using (var g = Graphics.FromImage(bmp))
        {
            g.Clear(Color.White);
            g.SmoothingMode = SmoothingMode.AntiAlias;

            // 背景雜訊
            for (int i = 0; i < 20; i++)
            {
                using (var pen = new Pen(Color.FromArgb(_rng.Next(150, 220), _rng.Next(150, 220), _rng.Next(150, 220)), 1))
                {
                    g.DrawLine(pen, _rng.Next(width), _rng.Next(height), _rng.Next(width), _rng.Next(height));
                }
            }

            // 文字 (逐字隨機位移/旋轉)
            using (var font = new Font("Arial", 22, FontStyle.Bold | FontStyle.Italic))
            using (var brush = new SolidBrush(Color.FromArgb(_rng.Next(0, 100), _rng.Next(0, 100), _rng.Next(0, 100))))
            {
                float x = 5;
                for (int i = 0; i < code.Length; i++)
                {
                    var state = g.Save();
                    g.TranslateTransform(x + 15, height / 2f);
                    g.RotateTransform(_rng.Next(-15, 15));
                    g.DrawString(code[i].ToString(), font, brush, -10, -12);
                    g.Restore(state);
                    x += 25;
                }
            }

            using (var ms = new MemoryStream())
            {
                bmp.Save(ms, ImageFormat.Png);
                return (code, ms.ToArray());
            }
        }
    }
}

跨平台 / 高併發替代方案

庫優點適用場景
ImageSharp純 managed、跨平台、執行緒安全、API 現代ASP.NET Core、Linux 容器、Serverless
SkiaSharpGoogle Skia 引擎、效能極佳、功能豐富高併發、複雜繪圖、PDF 生成
QuestPDF流式版面、支援中文、適合報表/文件動態 PDF/圖片報表

ImageSharp 範例 (現代標準)


using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.Fonts;

public byte[] GenerateWithImageSharp(string text)
{
    var font = SystemFonts.CreateFont("Arial", 48, FontStyle.Bold);
    var options = new TextOptions(font) { Origin = new PointF(10, 10), HorizontalAlignment = HorizontalAlignment.Left };
    
    // 自動測量文字大小
    var textSize = TextMeasurer.MeasureSize(text, options);
    int width = (int)textSize.Width + 20;
    int height = (int)textSize.Height + 20;

    using (var img = new Image(width, height, Color.LightGray))
    {
        img.Mutate(ctx => ctx.DrawText(options, text, Color.Black));
        
        using (var ms = new MemoryStream())
        {
            img.SaveAsPng(ms);
            return ms.ToArray();
        }
    }
}

總結

  • 舊專案/Windows 環境:System.Drawing 即可滿足基本需求。
  • 新專案/跨平台/高併發:**強烈建議 ImageSharp 或 SkiaSharp**。
  • 記得 using 釋放非受控資源 (GDI+ 物件、記憶體流)。
  • 字型授權:商業部署確認字型授權,或使用開源字型 (Noto Sans, Source Han Sans 等)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved