ASP.NET Core生成好看的图形验证码

引言

ASP.NET Core的验证码呢,稍微有一点曲折,因为默认System.Drawing没有Bitmap对象,也就没法绘制对象,不过通过NuGetZKWeb.System.Drawing 可引入Bitmap对象,进行验证码图片绘制

在这里插入图片描述

一、生成随机数

随机数就比较简单了,给定特定的字符数组,通过Random来生成随机数拼接成对应的字符串,就得到了我们的随验证码的随即字符,这里我简单进行了封装,仅供参考!

        /// <summary>
        /// 获取数字验证码
        /// </summary>
        /// <param name="n">验证码数</param>
        /// <returns></returns>
        public static string CreateNumCode(int n)
        {
    
    
            char[] numChar = {
    
     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

            string charCode = string.Empty;

            Random random = new Random();

            for (int i = 0; i < n; i++)
            {
    
    
                charCode += numChar[random.Next(numChar.Length)];
            }
            return charCode;
        }

        /// <summary>
        /// 获取字符验证码
        /// </summary>
        /// <param name="n">验证码数</param>
        /// <returns></returns>
        public static string CreateCharCode(int n)
        {
    
    
            char[] strChar = {
    
     'a', 'b','c','d','e','f','g','h','i','j','k','l','m',
                'n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3',
                '4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K',
                'L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

            string charCode = string.Empty;

            Random random = new Random();

            for (int i = 0; i < n; i++)
            {
    
    
                charCode += strChar[random.Next(strChar.Length)];
            }
            return charCode;
        }

二、绘制图片

绘制图片也就是所谓的验证码对于新手就比较陌生了,不过也很好理解,通过简单的梳理下逻辑步骤,就可以清晰明了。即:通过Bitmap创建画布Graphis执行画的动作,如:验证码的躁线噪点呈现的字符,通过MemoryStream写入内存,通过MemoryStream转换的数据去获取生成的对应验证码图,再用SessionCookie存储验证码即可完成!

1、画布

通过Bitmap对象创建画布

            //创建画布
            Bitmap bitmap = new Bitmap(codeW, codeH);
            Graphics graphics = Graphics.FromImage(bitmap);
            graphics.Clear(Color.White);

2、画躁线

躁线可提高验证码的可用性,通过给Graphics画笔Pen指定颜色位置即可完成!

            //颜色列表
            Color[] colors = {
    
     Color.Black, Color.Red, Color.Blue, Color.Green, Color.Orange, Color.Brown, Color.DarkBlue };
           
            //宽、高,字体大小
            int codeW = 74;
            int codeH = 36;
            int fontSize = 16;
            Random random = new Random();

            //画躁线
            for (int i = 0; i < n; i++)
            {
    
    
                int x1 = random.Next(codeW);
                int y1 = random.Next(codeH);
                int x2 = random.Next(codeW);
                int y2 = random.Next(codeH);
                Color color = colors[random.Next(colors.Length)];
                Pen pen = new Pen(color);
                graphics.DrawLine(pen, x1, y1, x2, y2);
            }

3、画噪点

噪点和躁线原理一致,不过这里要使用的是BitmapSetPixel来完成,很简单也很好理解!

            //画噪点
            for (int i = 0; i < 100; i++)
            {
    
    
                int x = random.Next(codeW);
                int y = random.Next(codeH);
                Color color = colors[random.Next(colors.Length)];
                bitmap.SetPixel(x, y, color);
            }

4、画验证码

            //画验证码
            for (int i = 0; i < n; i++)
            {
    
    
                string fontStr = fonts[random.Next(fonts.Length)];
                Font font = new Font(fontStr, fontSize);
                Color color = colors[random.Next(colors.Length)];
                graphics.DrawString(charCode[i].ToString(), font, new SolidBrush(color), (float)i * 15 + 2, (float)0);
            }

            //写入内存流
            try
            {
    
    
                MemoryStream stream = new MemoryStream();
                bitmap.Save(stream, ImageFormat.Jpeg);

                VerifyCode verifyCode = new VerifyCode()
                {
    
    
                    Code = charCode,
                    Image = stream.ToArray()
                };
                return verifyCode;
            }

            //释放资源
            finally
            {
    
    
                graphics.Dispose();
                bitmap.Dispose();
            }

三、完整代码示例

上述是分布讲解图形验证码的生成过程,以及组成结构,这里提供完整的代码,以供大家参考和应用!一共三部分:验证码结构、枚举类型(NUM:数字验证码,CHAR字符验证码),工具类,并提供Web调用代码!

public class VerifyCode
    {
    
    
        /// <summary>
        /// 验证码
        /// </summary>
        public string Code {
    
     get; set; }

        /// <summary>
        /// 验证码数据流
        /// </summary>
        public byte[] Image {
    
     get; set; }
    }
public enum VerifyCodeType
    {
    
    
        NUM,
        CHAR
    }
public static class VerifyCodeHelper
    {
    
    
        /// <summary>
        /// 获取验证码
        /// </summary>
        /// <param name="n">验证码数</param>
        /// <param name="type">类型 0:数字 1:字符</param>
        /// <returns></returns>
        public static VerifyCode CreateVerifyCode(int n, VerifyCodeType type)
        {
    
    
            //宽、高,字体大小
            int codeW = 74;
            int codeH = 36;
            int fontSize = 16;

            //初始化验证码
            string charCode = string.Empty;

            switch (type.ToString())
            {
    
    
                case "NUM":
                    charCode = CreateNumCode(n);
                    break;
                default:
                    charCode = CreateCharCode(n);
                    break;
            }

            //颜色列表
            Color[] colors = {
    
     Color.Black, Color.Red, Color.Blue, Color.Green, Color.Orange, Color.Brown, Color.DarkBlue };

            //字体列表
            string[] fonts = {
    
     "Times New Roman", "Verdana", "Arial", "Gungsuh" };

            //创建画布
            Bitmap bitmap = new Bitmap(codeW, codeH);
            Graphics graphics = Graphics.FromImage(bitmap);
            graphics.Clear(Color.White);

            Random random = new Random();

            //画躁线
            for (int i = 0; i < n; i++)
            {
    
    
                int x1 = random.Next(codeW);
                int y1 = random.Next(codeH);
                int x2 = random.Next(codeW);
                int y2 = random.Next(codeH);
                Color color = colors[random.Next(colors.Length)];
                Pen pen = new Pen(color);
                graphics.DrawLine(pen, x1, y1, x2, y2);
            }          

            //画噪点
            for (int i = 0; i < 100; i++)
            {
    
    
                int x = random.Next(codeW);
                int y = random.Next(codeH);
                Color color = colors[random.Next(colors.Length)];
                bitmap.SetPixel(x, y, color);
            }

            //画验证码
            for (int i = 0; i < n; i++)
            {
    
    
                string fontStr = fonts[random.Next(fonts.Length)];
                Font font = new Font(fontStr, fontSize);
                Color color = colors[random.Next(colors.Length)];
                graphics.DrawString(charCode[i].ToString(), font, new SolidBrush(color), (float)i * 15 + 2, (float)0);
            }

            //写入内存流
            try
            {
    
    
                MemoryStream stream = new MemoryStream();
                bitmap.Save(stream, ImageFormat.Jpeg);

                VerifyCode verifyCode = new VerifyCode()
                {
    
    
                    Code = charCode,
                    Image = stream.ToArray()
                };
                return verifyCode;
            }

            //释放资源
            finally
            {
    
    
                graphics.Dispose();
                bitmap.Dispose();
            }

        }

        /// <summary>
        /// 获取数字验证码
        /// </summary>
        /// <param name="n">验证码数</param>
        /// <returns></returns>
        public static string CreateNumCode(int n)
        {
    
    
            char[] numChar = {
    
     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

            string charCode = string.Empty;

            Random random = new Random();

            for (int i = 0; i < n; i++)
            {
    
    
                charCode += numChar[random.Next(numChar.Length)];
            }
            return charCode;
        }

        /// <summary>
        /// 获取字符验证码
        /// </summary>
        /// <param name="n">验证码数</param>
        /// <returns></returns>
        public static string CreateCharCode(int n)
        {
    
    
            char[] strChar = {
    
     'a', 'b','c','d','e','f','g','h','i','j','k','l','m',
                'n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3',
                '4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K',
                'L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

            string charCode = string.Empty;

            Random random = new Random();

            for (int i = 0; i < n; i++)
            {
    
    
                charCode += strChar[random.Next(strChar.Length)];
            }
            return charCode;
        }

    }
public class VerifyCodeController : Controller
    {
    
    
        public async Task<FileResult> GetVerifyCode()
        {
    
    
            var oldVerifyCode = HttpContext.Session.GetString("VerifyCode");
            if (!string.IsNullOrEmpty(oldVerifyCode))
            {
    
    
                HttpContext.Session.SetString("VerifyCode", "");
            }
            return await Task.Factory.StartNew(() =>
            {
    
    
                VerifyCode verifyCode = VerifyCodeHelper.CreateVerifyCode(4, VerifyCodeType.CHAR);
                HttpContext.Session.SetString("VerifyCode", verifyCode.Code);
                return File(verifyCode.Image, @"image/jpeg"); ;
            });
        }
    }
<img src="/VerifyCode/GetVerifyCode" onclick="this.src=this.src+'?'"/>

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_42799562/article/details/114481655