ZhiYi/ZhiYi.Core.Application/Captcha/CaptchaService.cs

169 lines
6.1 KiB
C#
Raw Normal View History

2025-02-21 01:14:39 +00:00

using SixLabors.ImageSharp.Drawing.Processing;
namespace ZhiYi.Core.Application.Captcha
{
public class CaptchaService
{
private readonly IDatabase _redis;
public CaptchaService(IConnectionMultiplexer redis)
{
_redis = redis.GetDatabase();
}
// 生成验证码图片 linux不支持
/*public byte[] GenerateCaptchaImage(string captchaText)
{
using var bitmap = new Bitmap(120, 40);
using var graphics = Graphics.FromImage(bitmap);
graphics.Clear(Color.White);
// 绘制验证码文本
var font = new Font("Arial", 20, FontStyle.Bold);
var brush = new SolidBrush(Color.Black);
graphics.DrawString(captchaText, font, brush, 10, 10);
// 添加干扰线
var random = new Random();
for (int i = 0; i < 10; i++)
{
var pen = new Pen(Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)), 1);
graphics.DrawLine(pen, random.Next(120), random.Next(40), random.Next(120), random.Next(40));
}
// 将图片转换为字节数组
using var stream = new MemoryStream();
bitmap.Save(stream, ImageFormat.Png);
return stream.ToArray();
}*/
// 生成随机验证码文本
public string GenerateCaptchaText(int length = 4)
{
const string chars = "ZhiYiCode";
var random = new Random();
var captchaText = new StringBuilder();
for (int i = 0; i < length; i++)
{
captchaText.Append(chars[random.Next(chars.Length)]);
}
return captchaText.ToString();
}
public byte[] GenerateCaptchaImageByImageSharp(string captchaText)
{
// 创建一个 120x40 的空白图片
using var image = new Image<Rgba32>(120, 40);
// 设置背景颜色为白色
image.Mutate(ctx => ctx.Fill(SixLabors.ImageSharp.Color.White));
// 加载字体
// 创建字体和文本选项
var fontCollection = new FontCollection();
//var fontFamily = fontCollection.Add("Arial"); // 使用Arial字体或者指定其他字体
var fontFamily = SystemFonts.Get("Arial"); // 使用系统字体
var font = fontFamily.CreateFont(20); // 创建Font对象指定字体大小
// 绘制验证码文本
var textOptions = new RichTextOptions(font)
{
Origin = new PointF(10, 10), // 文本起始位置
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Top
};
image.Mutate(ctx => ctx.DrawText(textOptions, captchaText, Color.Black));
// 添加干扰线
var random = new Random();
for (int i = 0; i < 10; i++)
{
var color = Color.FromRgb((byte)random.Next(256), (byte)random.Next(256), (byte)random.Next(256));
var pen = new SolidPen(color, 1); // 使用 SolidPen 替代 Pen
var start = new PointF(random.Next(120), random.Next(40));
var end = new PointF(random.Next(120), random.Next(40));
image.Mutate(ctx => ctx.DrawLine(pen, start, end));
}
// 将图片转换为字节数组
using var stream = new MemoryStream();
image.Save(stream, new SixLabors.ImageSharp.Formats.Png.PngEncoder());
return stream.ToArray();
}
/*/// <summary>
/// 绘制验证码图片,返回图片的字节数组
/// </summary>
/// <param name="code"></param>
/// <param name="length">验证码长度</param>
/// <returns></returns>
public byte[] DrawVerifyCode(out string code, int length = 6)
{
code = _stringHelper.GenerateRandom(length);
using var img = new Image<Rgba32>(4 + 16 * code.Length, 40);
var font = new Font(SystemFonts.Families.First(), 16, FontStyle.Regular);
var codeStr = code;
img.Mutate(x =>
{
x.BackgroundColor(Color.WhiteSmoke);
var r = new Random();
//画噪线
for (var i = 0; i < 4; i++)
{
int x1 = r.Next(img.Width);
int y1 = r.Next(img.Height);
int x2 = r.Next(img.Width);
int y2 = r.Next(img.Height);
x.DrawLine(new Pen(_colors.RandomGet(), 1L), new PointF(x1, y1), new PointF(x2, y2));
}
//画验证码字符串
for (int i = 0; i < codeStr.Length; i++)
{
x.DrawText(codeStr[i].ToString(), font, _colors.RandomGet(), new PointF((float)i * 16 + 4, 8));
}
});
using var stream = new MemoryStream();
img.SaveAsPng(stream);
return stream.GetBuffer();
}
/// <summary>
/// 绘制验证码图片返回图片的Base64字符串
/// </summary>
/// <param name="code"></param>
/// <param name="length">验证码长度</param>
/// <returns></returns>
public string DrawVerifyCodeBase64String(out string code, int length = 6)
{
var bytes = DrawVerifyCode(out code, length);
return "data:image/png;base64," + Convert.ToBase64String(bytes);
}*/
// 存储验证码
public void StoreCaptcha(string captchaId, string captchaText)
{
_redis.StringSet(captchaId, captchaText, TimeSpan.FromMinutes(5)); // 5 分钟有效期
}
// 验证用户输入的验证码
public bool ValidateCaptcha(string captchaId, string userInput)
{
var value = _redis.StringGet($"captcha:{captchaId}");
if (value.HasValue)
{
return value == userInput;
}
return false;
}
}
}