169 lines
6.1 KiB
C#
169 lines
6.1 KiB
C#
|
|
|||
|
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;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|