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

169 lines
6.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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