.net 验证码(window和Linux通用)

1.包引用可使用最新版本

<PackageReference Include="SixLabors.Fonts" Version="1.0.0-beta15" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta13" />

2.使用类

public class CaptchaHelper
{
    private const string Letters = "1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,T,U,V,W,X,Y,Z";

    /// <summary>
    /// 生成验证码随机值
    /// </summary>
    /// <param name="codeLength"></param>
    /// <returns></returns>
    private Task<string> GenerateRandomCaptchaAsync(int codeLength = 4)
    {
        var array = Letters.Split(new[] { ',' });
        var random = new Random();
        var temp = -1;
        var captcheCode = string.Empty;
        for (int i = 0; i < codeLength; i++)
        {
            if (temp != -1)
                random = new Random(i * temp * unchecked((int)DateTime.Now.Ticks));

            var index = random.Next(array.Length);
            if (temp != -1 && temp == index)
                return GenerateRandomCaptchaAsync(codeLength);

            temp = index;
            captcheCode += array[index];
        }
        return Task.FromResult(captcheCode);
    }

    /// <summary>
    /// 生成验证码及图片
    /// </summary>
    /// <param name="captchaCode"></param>
    /// <param name="width"></param>
    /// <param name="height"></param>
    /// <returns></returns>
    public async Task<(string code, MemoryStream ms)> GenerateCaptchaImageAsync(int codeLength = 4, int width = 0, int height = 30)
    {
        var captchaCode = await GenerateRandomCaptchaAsync(codeLength);
        //验证码颜色集合
        Color[] colors = { Color.Black, Color.Red, Color.DarkBlue, Color.Green, Color.Orange, Color.Brown, Color.DarkCyan, Color.Purple };
        //验证码字体集合
        string[] fonts = { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial" };
        var r = new Random();
        
        if(width == 0) { width = captchaCode.Length * 25; }
        //定义图像的大小,生成图像的实例
        using var image = new Image<Rgba32>(width, height);

        // 字体
        var font = SystemFonts.CreateFont(SystemFonts.Families.First().Name, 25, FontStyle.Bold);

        image.Mutate(ctx =>
        {
            // 白底背景
            ctx.Fill(Color.White);

            // 画验证码
            for (int i = 0; i < captchaCode.Length; i++)
            {
                ctx.DrawText(captchaCode[i].ToString()
                    , font
                    , colors[r.Next(colors.Length)]
                    , new PointF(20 * i + 10, r.Next(2, 12)));
            }

            // 画干扰线
            for (int i = 0; i < 10; i++)
            {
                var pen = new Pen(colors[r.Next(colors.Length)], 1);
                var p1 = new PointF(r.Next(width), r.Next(height));
                var p2 = new PointF(r.Next(width), r.Next(height));

                ctx.DrawLines(pen, p1, p2);
            }

            // 画噪点
            for (int i = 0; i < 80; i++)
            {
                var pen = new Pen(colors[r.Next(colors.Length)], 1);
                var p1 = new PointF(r.Next(width), r.Next(height));
                var p2 = new PointF(p1.X + 1f, p1.Y + 1f);

                ctx.DrawLines(pen, p1, p2);
            }
        });
        using var ms = new MemoryStream();

        // gif 格式
        image.SaveAsGif(ms);
        return (captchaCode, ms);
    }
}

3.使用实例

public async Task<IActionResult> GetCaptcha()
{
   var captchaHelper = new CaptchaHelper();
   var captcha = await captchaHelper.GenerateCaptchaImageAsync();
   this.HttpContext.Session.SetString("captcha", captcha.code);
   return File(captcha.ms.ToArray(), "image/gif");
}

 

posted @ 2024-08-16 16:27  北极星下落不明  阅读(12)  评论(0)    收藏  举报