#if NET461
using System.Web;
#else
using Microsoft.AspNetCore.Http;
#endif
using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using Masuit.Tools.AspNetCore.Mime;
using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Formats.Webp;
namespace Masuit.Tools.Strings
{
///
/// 画验证码
///
public static class ValidateCode
{
///
/// 生成验证码
///
/// 指定验证码的长度
/// 验证码字符串
public static string CreateValidateCode(int length)
{
string ch = "abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ1234567890@#$%&?";
byte[] b = new byte[4];
using var cpt = RandomNumberGenerator.Create();
cpt.GetBytes(b);
var r = new Random(BitConverter.ToInt32(b, 0));
var sb = new StringBuilder();
for (int i = 0; i < length; i++)
{
sb.Append(ch[r.StrictNext(ch.Length)]);
}
return sb.ToString();
}
///
/// 创建验证码的图片
///
/// 验证码序列
/// 当前的HttpContext上下文对象
/// 字体大小,默认值28px
/// The operation failed.
public static byte[] CreateValidateGraphic(this HttpContext context, string validateCode, int fontSize = 28)
{
var font = SystemFonts.Families.Where(f => new[] { "Consolas", "KaiTi", "NSimSun", "SimSun", "SimHei", "Microsoft YaHei UI", "Arial" }.Contains(f.Name)).OrderByRandom().FirstOrDefault().CreateFont(fontSize);
var measure = TextMeasurer.Measure(validateCode, new TextOptions(font));
var width = (int)Math.Ceiling(measure.Width * 1.5);
var height = (int)Math.Ceiling(measure.Height + 5);
using var image = new Image(width, height);
//生成随机生成器
Random random = new Random();
//清空图片背景色
image.Mutate(g =>
{
g.BackgroundColor(Color.White);
//画图片的干扰线
for (int i = 0; i < 75; i++)
{
int x1 = random.StrictNext(width);
int x2 = random.StrictNext(width);
int y1 = random.StrictNext(height);
int y2 = random.StrictNext(height);
g.DrawLines(new Pen(new Color(new Rgba32((byte)random.StrictNext(255), (byte)random.StrictNext(255), (byte)random.StrictNext(255))), 1), new PointF(x1, y1), new PointF(x2, y2));
}
//渐变.
var brush = new LinearGradientBrush(new PointF(0, 0), new PointF(width, height), GradientRepetitionMode.Repeat, new ColorStop(0.5f, Color.Blue), new ColorStop(0.5f, Color.DarkRed));
g.DrawText(validateCode, font, brush, new PointF(3, 2));
//画图片的边框线
g.DrawLines(new Pen(Color.Silver, 1), new PointF(0, 0), new PointF(width - 1, height - 1));
});
//画图片的前景干扰点
for (int i = 0; i < 350; i++)
{
int x = random.StrictNext(image.Width);
int y = random.StrictNext(image.Height);
image[x, y] = new Rgba32(random.StrictNext(255), random.StrictNext(255), random.StrictNext(255));
}
//保存图片数据
using MemoryStream stream = new MemoryStream();
image.Save(stream, WebpFormat.Instance);
//输出图片流
context.Response.Clear();
context.Response.ContentType = ContentType.Jpeg;
return stream.ToArray();
}
}
}