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;
|
||
}
|
||
}
|
||
}
|