在C#开发中,生成验证码图片是很多项目的基础需求,核心是通过System.Drawing命名空间下的类完成画布创建、字符绘制、干扰元素添加等操作,最终输出为图片流供前端展示。

核心实现思路
生成验证码图片的整体流程可以分为四个步骤:
- 生成指定长度的随机验证码字符,包含数字、大小写字母
- 创建指定尺寸的位图对象作为画布
- 使用Graphics类在画布上绘制字符、背景色、干扰线和噪点
- 将位图转换为内存流输出为图片格式
关键类说明
实现过程中会用到几个核心类:
Random:用于生成随机字符和随机位置、颜色参数Bitmap:表示位图对象,作为绘制的画布载体Graphics:提供绘制线条、文字、形状的方法MemoryStream:将生成的图片保存到内存流中,方便输出到响应
完整项目实例源码
以下是一个完整的ASP.NET MVC项目中生成验证码的控制器代码,包含验证码生成和验证两个方法:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Web.Mvc;
using System.Collections.Generic;
namespace CaptchaDemo.Controllers
{
public class CaptchaController : Controller
{
// 存储验证码的Session键
private const string CAPTCHA_SESSION_KEY = "CurrentCaptcha";
/// <summary>
/// 生成验证码图片
/// </summary>
/// <returns>验证码图片文件结果</returns>
public ActionResult GenerateCaptcha()
{
// 1. 生成4位随机验证码字符
string captchaText = GenerateRandomText(4);
// 将验证码存入Session,用于后续验证
Session[CAPTCHA_SESSION_KEY] = captchaText;
// 2. 创建位图对象,设置宽高
int width = 120;
int height = 40;
using (Bitmap bitmap = new Bitmap(width, height))
{
// 3. 创建Graphics绘图对象
using (Graphics g = Graphics.FromImage(bitmap))
{
// 设置背景色为浅灰色
g.Clear(Color.LightGray);
// 设置文字字体
Font font = new Font("Arial", 20, FontStyle.Bold);
// 设置文字颜色为随机深色
Brush textBrush = new SolidBrush(GetRandomDarkColor());
// 绘制验证码文字,每个字符间隔一定距离
for (int i = 0; i < captchaText.Length; i++)
{
g.DrawString(captchaText[i].ToString(), font, textBrush, 10 + i * 25, 5);
}
// 4. 添加干扰线
Random random = new Random();
for (int i = 0; i < 5; i++)
{
Pen linePen = new Pen(GetRandomLightColor(), 1);
Point startPoint = new Point(random.Next(width), random.Next(height));
Point endPoint = new Point(random.Next(width), random.Next(height));
g.DrawLine(linePen, startPoint, endPoint);
}
// 5. 添加随机噪点
for (int i = 0; i < 100; i++)
{
int x = random.Next(width);
int y = random.Next(height);
bitmap.SetPixel(x, y, GetRandomLightColor());
}
}
// 6. 将位图转换为内存流输出
using (MemoryStream ms = new MemoryStream())
{
bitmap.Save(ms, ImageFormat.Jpeg);
return File(ms.ToArray(), "image/jpeg");
}
}
}
/// <summary>
/// 验证用户输入的验证码是否正确
/// </summary>
/// <param name="inputCaptcha">用户输入的验证码</param>
/// <returns>验证结果</returns>
public JsonResult ValidateCaptcha(string inputCaptcha)
{
string sessionCaptcha = Session[CAPTCHA_SESSION_KEY] as string;
if (string.IsNullOrEmpty(sessionCaptcha) || string.IsNullOrEmpty(inputCaptcha))
{
return Json(new { success = false, message = "验证码不能为空" }, JsonRequestBehavior.AllowGet);
}
// 忽略大小写比较
bool isValid = sessionCaptcha.Equals(inputCaptcha, StringComparison.OrdinalIgnoreCase);
return Json(new { success = isValid, message = isValid ? "验证成功" : "验证码错误" }, JsonRequestBehavior.AllowGet);
}
/// <summary>
/// 生成指定长度的随机字符
/// </summary>
private string GenerateRandomText(int length)
{
string chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
Random random = new Random();
char[] result = new char[length];
for (int i = 0; i < length; i++)
{
result[i] = chars[random.Next(chars.Length)];
}
return new string(result);
}
/// <summary>
/// 获取随机深色,用于文字绘制
/// </summary>
private Color GetRandomDarkColor()
{
Random random = new Random();
int r = random.Next(0, 128);
int g = random.Next(0, 128);
int b = random.Next(0, 128);
return Color.FromArgb(r, g, b);
}
/// <summary>
/// 获取随机浅色,用于干扰线和噪点
/// </summary>
private Color GetRandomLightColor()
{
Random random = new Random();
int r = random.Next(128, 256);
int g = random.Next(128, 256);
int b = random.Next(128, 256);
return Color.FromArgb(r, g, b);
}
}
}
使用说明
将上述控制器添加到ASP.NET MVC项目后,前端可以通过以下方式调用:
- 在页面中通过<img>标签的src属性指向
/Captcha/GenerateCaptcha即可展示验证码图片 - 用户提交表单时,将输入的验证码值传入
/Captcha/ValidateCaptcha接口即可完成验证 - 如果需要调整验证码长度、图片尺寸,可以修改对应方法的参数即可
注意事项
使用System.Drawing相关类时,需要注意以下两点:
- 如果是.NET Core及以上版本,需要安装
System.Drawing.CommonNuGet包,且Windows环境下可直接使用,Linux环境需要安装libgdiplus依赖 - 验证码Session的过期时间可以根据项目需求调整,避免长期有效带来安全风险